does anyone know why
System.out.println(e.getFirstIndex());
System.out.println(e.getLastIndex());
both does nothing? is my Listener not registered properly? i am trying to know when a certain cell is selected and do something to it. Like setting a default text for that cell when it is selected either by mouse or key.
package VLGui;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.util.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.Timer;
import javax.swing.table.*;
import VLCore.cellSelectedListener;
public class mainFrame extends JFrame{
private JLabel lblTime;
private Vector columnName = new Vector();
private Vector tblData = new Vector();
private JTable JTbl;
private Timer timer = new Timer(1000,new MyListener());
private JPanel topPnl,cenPnl,btmPnl;
private Calendar time;
private Object[] columnNames = {"Veh No.","Description","Time In","Time Out"};
public mainFrame()
{
timer.start();
//jtable settings
JTbl = new JTable(new DefaultTableModel(columnNames,1));
JTbl.setPreferredScrollableViewportSize(JTbl.getPreferredSize());
JTbl.setFillsViewportHeight(true);
JTbl.setCellSelectionEnabled(false);
JTbl.setColumnSelectionInterval(0,0);
JTbl.setRowSelectionInterval(0,0);
JTbl.getSelectionModel().addListSelectionListener(new cellSelectedListener(JTbl));
//Settings
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Vehicle Log");
setSize(500,1000);
setVisible(true);
//Dec
JScrollPane tableContainer = new JScrollPane(JTbl);
topPnl = new JPanel();
cenPnl = new JPanel();
btmPnl = new JPanel();
lblTime = new JLabel();
//Adding Components
topPnl.add(lblTime,BorderLayout.CENTER);
cenPnl.add(tableContainer);
getContentPane().add(topPnl,BorderLayout.NORTH);
getContentPane().add(cenPnl,BorderLayout.CENTER);
//add(btmPnl);
}
public class MyListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
time = Calendar.getInstance();
lblTime.setText(time.getTime().toString());
lblTime.repaint();
}
}
}
package VLCore;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class cellSelectedListener implements ListSelectionListener {
private JTable jTbl;
public cellSelectedListener()
{
}
public cellSelectedListener(JTable tbl)
{
jTbl = tbl;
}
#Override
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel)e.getSource();
System.out.println(e.getFirstIndex());
System.out.println(e.getLastIndex());
}
}
The problem is, the row is already selected.
The tables selection model relates to the selection changes of the rows.
If you change the order in which you register the listener as follows...
JTbl.getSelectionModel().addListSelectionListener(new cellSelectedListener(JTbl));
JTbl.setColumnSelectionInterval(0, 0);
JTbl.setRowSelectionInterval(0, 0);
You will see the row selection change.
Update code review...
Generally, this JTbl.setPreferredScrollableViewportSize(JTbl.getPreferredSize()); is not a good idea. You really want to leave it up to the scroll pane to make these kind of decisions. You can alter the column sizes if you really want to effect the width of the table.
Java naming conventions suggest that all instance variables start with a lower case character, soJTbl would become jTbl and all classes start with an upper case, so mainFrame would become MainFrame...small thing, but it's what people are really use to.
Related
I am working on a basic Java Swing UI application, which seems to be working correctly, except for an issue I've noticed when using the form I created.
The problem is when I am typing in the text boxes, holding down a key seems to break the form--ie, after taking this action, the text boxes no longer seem to accept any input. I find it hard to believe this is a released issue with Java Swing components, but I also can't see how it would be related to my code. Has anyone seen a similar issue before? I am using OS x with Intellij IDEA if that is relevant.
My form is defined thusly:
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
#SuppressWarnings("serial")
public class LoginDialogMcve extends JFrame {
protected JTextField stringEntry, dateEntry;
public LoginDialogMcve() {
super("Create Textbox");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
this.stringEntry = new JTextField(5);
add(this.stringEntry);
this.dateEntry = new JTextField(5);
add(this.dateEntry);
}
public static void main(String... args) {
LoginDialogMcve me = new LoginDialogMcve();
me.pack();
me.setLocationByPlatform(true);
me.setVisible(true);
}
}
Edit: Thanks for the feedback, this is quite possibly not a Java problem. Could have something to do with OSx... Uploaded simpler example with mcve
My MCVE that works fine. Test it yourself to see.
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
// import net.miginfocom.swing.MigLayout;
#SuppressWarnings("serial")
public class LoginDialogMcve extends JFrame {
protected JTextField stringEntry, dateEntry;
protected JLabel stringEntryLabel, dateEntryLabel;
protected JButton print;
protected Action validateAction;
public LoginDialogMcve() {
super("Create Textbox");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
// setLayout(new MigLayout("ins 10, gap 5",
// "[][grow]",
// "[][][]"));
this.stringEntryLabel = new JLabel("Name:");
add(this.stringEntryLabel);
this.stringEntry = new JTextField(5);
add(this.stringEntry);
this.dateEntryLabel = new JLabel("Date:");
add(this.dateEntryLabel);
this.dateEntry = new JTextField(5);
add(this.dateEntry);
this.validateAction = new MyAction();
this.print = new JButton(this.validateAction);
add(this.print);
getRootPane().getActionMap().put("validate", this.validateAction);
}
public static void main(String... args) {
LoginDialogMcve me = new LoginDialogMcve();
me.pack();
me.setLocationByPlatform(true);
me.setVisible(true);
}
public class MyAction extends AbstractAction {
public MyAction() {
super("Validate");
}
#Override
public void actionPerformed(ActionEvent e) {
// lots of irrelevant code
}
}
}
I'm failing to understand why my yankee and whiskey JButtons aren't working. Right now I only want them to close the program when romeo is greater than 1 and sierra is greater than 1.
import java.awt.*;
import java.lang.*;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.*;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import java.util.Scanner;
public class AlphaMenu extends JFrame /*implements actionPerformed*/
{
private GraphicsDevice gamma;
public JButton charlie, zulu, yankee, xray;
public JFrame beta;
public JPanel delta, echo, foxtrot, golf, hotel;
public JTextArea whiskey, victor;
public BorderLayout uniform;
public ImageIcon bg;
public JLabel tango;
public int sierra, romeo;
public Integer quebec, papa;
public ActionEvent oscar;
public ActionEvent november;
public AlphaMenu()
{
//Initialization of Objects
charlie = new JButton("EXIT");
zulu = new JButton("Enter Time");
yankee = new JButton("Enter Amount of Money");
xray = new JButton("Calculate");
sierra = 0;
romeo = 0;
quebec = new Integer(0);
papa = new Integer(0);
whiskey = new JTextArea(2, 15);
victor = new JTextArea(2, 15);
bg = new ImageIcon("background.gif");
beta = new JFrame();
delta = new JPanel();
echo = new JPanel();
foxtrot = new JPanel();
golf = new JPanel();
hotel = new JPanel();
uniform = new BorderLayout();
ImageIcon bg = new ImageIcon("background.gif");
tango = new JLabel("");
tango.setIcon(bg);
//Modification of panels
beta.add(delta, uniform.PAGE_END);
beta.add(golf, uniform.PAGE_START);
beta.add(echo, uniform.LINE_START);
beta.add(foxtrot, uniform.LINE_END);
beta.add(hotel, uniform.CENTER);
golf.add(tango);
//Modification of JButton charlie & adding of JButtons
charlie.setPreferredSize(new Dimension(100, 50));
delta.add(charlie);
charlie.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
echo.add(whiskey);
echo.add(yankee);
foxtrot.add(victor);
foxtrot.add(zulu);
//Modification of JFrame beta
beta.setUndecorated(true);
beta.setExtendedState(JFrame.MAXIMIZED_BOTH);
beta.setResizable(false);
beta.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
beta.setVisible(true);
}
public void buttonSetup() throws NumberFormatException
{
//Modification of JButton yankee & JTextArea whiskey & int sierra
romeo = quebec.parseInt(whiskey.getText());
yankee.setPreferredSize(new Dimension(300, 50));
yankee.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent oscar)
{
System.exit(0);
}
});
//Modification of JButton zulu & JTextArea victor & int romeo
sierra = papa.parseInt(victor.getText());
zulu.setPreferredSize(new Dimension(300, 50));
zulu.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent november)
{
System.exit(0);
}
});
}
public void actionPerformed(ActionEvent e)
{
}
public static void main(String[] args)
{
new AlphaMenu();
}
}
So, you have two JTextArea (JTextField would probably be better) and a button. you want some buttons to execute exit when the text of both textareas is an integer greater than 1.
seems that your buttonSetup() function isn't called anywhere.
Anyway, I'd create an ActionListener that reads the texts, converts to integer, tests your condition and executes exit(). This ActionListener should be added to all the buttons you want to perform the action
final ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent event) {
try {
final int intRomeo = Integer.parseInt(romeo.getText());
final int intSierra = Integer.parseInt(sierra .getText());
if (intRomeo > 1 && intSierra > 1) {
// whatever you want to do
System.exit(0);
}
} catch (/*NumberFormat*/ Exception e) {
// ...not integers
}
};
}
whiskey.addActionListener(al);
yankee.addActionListener(al);
I have to add: the variable names you are using are really bad. Consider choosing something more significative.
For starters, readability...it would probably help the "sloppiness" if you used more appropriate names for your variables, indented different sections of code, and used comments to help describe sections in layman's terms. Maybe "btnExit" and "btnCalculate" would help make things a little easier to navigate.
Moving forward, you also don't have two different classes here, you have one class with several methods. Which is fine but wanted to inform you of that. I think maybe you need to add the buttons to their panels after your action listeners and formatting for each button. I'm just getting into some swing stuff myself and I've noticed moving the .add() functions around in the code has helped when I run into issues like this. Try the following bellow. I indented and used new naming conventions for the comments, but the code uses your convention.
//add the pnlEcho to frmBeta
beta.add(echo, uniform.LINE_START);
//format btnYankee
yankee.setPreferredSize(new Dimension(300, 50));
//btnYankee action listener
yankee.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { //default action event
System.exit(0); //you could use this
beta.dispose(); //or you could dispose the frame and
//do more work after it is gone
}
});
//add btnYankee to pnlEcho
echo.add(yankee);
I'm failing to understand why my yankee and whiskey JButtons aren't
working
The variable wiskey is not JButton type but JTextArea type.
I'd like to create a Java Swing Photo Album but I can't manage to find the right way to do it. I think it should be to create two ArrayList, one to stock the photo objects and another one to stock the buttons.
After that I should find a way to assign each images to the buttons and add them into the panel.
My question is : Do you think it is the right way to do it and if so, could you give me a hint? (For the last class at the bottom)
Here's my code at the moment :
Main :
import javax.swing.JFrame;
public class Main extends JFrame {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new AlbumFrame();
}
});
}
}
AlbumFrame :
import java.awt.BorderLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AlbumFrame extends JFrame {
private JPanel MenuPanel;
private JPanel PhotoPanel;
public AlbumFrame(){
super("JPhone");
setLayout(new BorderLayout());
PhotoPanel = new PhotoPanel();
add(PhotoPanel,BorderLayout.CENTER);
MenuPanel = new MenuPanel();
add(MenuPanel,BorderLayout.SOUTH);
setSize(480,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
MenuPanel
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.filechooser.FileNameExtensionFilter;
public class MenuPanel extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
private JButton backButton;
private JButton homeButton;
private JButton turnButton;
private JButton addButton;
final private JFileChooser fc;
public MenuPanel(){
fc = new JFileChooser();
backButton = new JButton(new ImageIcon(getClass().getResource("/Images/back.png")));
homeButton = new JButton(new ImageIcon(getClass().getResource("/Images/home.png")));
turnButton = new JButton(new ImageIcon(getClass().getResource("/Images/turn.png")));
addButton = new JButton(new ImageIcon(getClass().getResource("/Images/add.png")));
backButton.setPreferredSize(new Dimension(55,55));
homeButton.setPreferredSize(new Dimension(55,55));
turnButton.setPreferredSize(new Dimension(55,55));
addButton.setPreferredSize(new Dimension(55,55));
backButton.addActionListener(this);
homeButton.addActionListener(this);
turnButton.addActionListener(this);
addButton.addActionListener(this);
setLayout(new FlowLayout(FlowLayout.CENTER));
add(backButton);
add(homeButton);
add(turnButton);
add(addButton);
}
public void actionPerformed(ActionEvent e) {
JButton clicked = (JButton)e.getSource();
//Test for the moment
if(clicked == backButton){
System.out.println("back");
}else if(clicked == homeButton){
System.out.println("home");
}else if(clicked == turnButton){
System.out.println("turn");
}else if(clicked == addButton){
int returnVal = fc.showOpenDialog(MenuPanel.this);
if(returnVal == JFileChooser.APPROVE_OPTION){
File file = fc.getSelectedFile();
}
}
}
}
PhotoPanel
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JPanel;
public class PhotoPanel extends JPanel implements ActionListener {
ArrayList<Photo> Album = new ArrayList<Photo>();
ArrayList<JButton> Buttons = new ArrayList<JButton>();
public PhotoPanel(){
setLayout(new FlowLayout(FlowLayout.CENTER));
}
public void actionPerformed(ActionEvent e) {
}
}
I would use separate class like PhotoCard to avoid lists:
class PhotoCard {
public PhotoCard(Photo photo) {
add(photo);
// also add buttons, listeners, etc.
}
}
that holds necessary data and initializes listeners.
And then class can be added to to your PhotoPanel:
PhotoPanel.add(new PhotoCard(...));
I am using a DAO Factory to get my Data from the database. When i am running my program the data is showing in the printline so he is getting it out of the database. But i want it to show in my JTable but this one is empty and i dont know how to fill it.
Code JFrame:
package View;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.WindowConstants;
import javax.swing.table.TableModel;
import Controller.VerwijderController;
import Model.OefeningenListModel;
import Model.OefeningenTableModel;
public class VerwijderenHome extends JFrame {
private JList LijstOefening;
private JScrollPane jScrollPane1;
private Container window = getContentPane();
private JButton delete;
private VerwijderController Controller;
private JTable tabel;
public VerwijderenHome()
{
initGUI();
}
public void addDeleteListener(ActionListener a){
delete.addActionListener(a);
}
private void initGUI() {
setPreferredSize(new Dimension(800, 600));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLayout(null);
setVisible(true);
JTable table = new JTable(new OefeningenTableModel());
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBounds(50, 50, 300, 60);
window.add(scrollPane);
delete = new JButton("Delete");
delete.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
delete.setBounds(50, 265, 100, 30);
window.add(delete);
pack();
Controller = new VerwijderController();
addDeleteListener(Controller);
}
public JButton getDelete(){
return delete;
}
public JList getLijst()
{
return LijstOefening;
}
}
Code DefaultTableModel?? (Dont know if i must use this one)
package Model;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Vector;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import datapackage.DAOFactory;
public class OefeningenTableModel extends DefaultTableModel {
ArrayList<Oefening> oefeningen;
public OefeningenTableModel(){
oefeningen = DAOFactory.getFactory(0).getIDAOOefening().load();
}
}
The DefaultTableModel is backed by a Vector representing the columns and rows of the table model.
You've provided your own ArrayList of objects, but you've not overridden the methods you will require to supply that data back to the table. The DefaultTableModel has no idea of your ArrayList
Try overridding some of the following;
public class OefeningenTableModel extends AbstractTableModel {
ArrayList<Oefening> oefeningen;
public OefeningenTableModel(){
oefeningen = DAOFactory.getFactory(0).getIDAOOefening().load();
}
#Override
public int getRowCount() {
return oefeningen.getSize();
}
#Override
public int getColumnCount() {
// You'll need to fill this out to meet your requirements
}
#Override
public String getColumnName(ing column) {
// You'll need to fill this out to meet your requirements
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
// You'll need to fill this out to meet your requirements
}
}
Take the time to have read through How to use Tables.
Does anyone have a good example of how to Add/Remove rows from a JTable using a custom table model? The issue I seem to be having is how to have the table keep updating when I add or remove items.
The real simple idea here is to have an add and remove button above my table which allows the user on the fly to change the table.
Here is example for adding row:
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
public class RowAdder extends JFrame {
final SimpleModel tableData = new SimpleModel();
JTable table = new JTable(tableData);
public static void main(String[] args) {
RowAdder ra = new RowAdder();
ra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ra.setSize(400, 300);
ra.setVisible(true);
}
public RowAdder() {
final JTextField textField = new JTextField();
setLayout(new BorderLayout());
add(new JScrollPane(table), BorderLayout.CENTER);
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
tableData.addText(textField.getText());
textField.setText("");
}
});
add(textField, BorderLayout.SOUTH);
}
}
class SimpleModel extends AbstractTableModel {
Vector textData = new Vector();
public void addText(String text) {
textData.addElement(text);
fireTableDataChanged();
}
public int getRowCount() {
return textData.size();
}
public int getColumnCount() {
return 3;
}
public Object getValueAt(int row, int column) {
return textData.elementAt(row);
}
}
above ref from : http://www.java2s.com/Tutorial/Java/0240__Swing/AddrowstoaTable.htm
Checkout this tutorial about JTable:
http://download.oracle.com/javase/tutorial/uiswing/components/table.html
Specifically for table model check:
http://download.oracle.com/javase/tutorial/uiswing/components/table.html#data
I think this tutorial should answer all your question.
You have to notify the JTable object on changes of the underlying table model. The table is not observing the model but waiting for events.
After every change (or set of changes), create a TableModelEvent and call the tables tableChanged method.