So I have this application with a JTable in it. The JTable is inside of a JScrollPane and JScrollPane is painted on a JFrame.
Now in my application I open a new windows to add a new row to that table and after I click a button to save the changes, the new window closes.
Now I have tried adding these lines after the new window is closed:
askTableInfo(); //a method to save the info in database to table and then save the table to variable 'table'
table.repaint();
scrollPane.repaint();
And of course repaint(); by it self. But it still does not seem to update my table in the JFrame.
What could be the issue here?
public class AppWindow extends JFrame implements ActionListener {
String user = "";
JLabel greetText = new JLabel();
JPanel panel = new JPanel();
JPanel panel2 = new JPanel(new GridLayout(1, 3));
JScrollPane scrollPane;
JTable tabel;
JButton newBook = new JButton("Add a book");
JButton deleteBook = new JButton("Remove a book");
JButton changeBook = new JButton("Change a book");
int ID;
public AppWindow(String user, int ID) {
this.ID = ID;
this.user = user;
setSize(500, 500);
setTitle("Books");
setLayout(new BorderLayout());
greetText.setText("Hi "+user+" here are your books:");
add(greetText, BorderLayout.NORTH);
askData();
panel.add(scrollPane);
add(panel, BorderLayout.CENTER);
panel2.add(newBook);
panel2.add(deleteBook);
panel2.add(changeBook);
add(paneel2, BorderLayout.SOUTH);
newBook.addActionListener(this);
setVisible(true);
}
private void askData() {
DataAsker asker = null;
try {
asker = new AndmeKysija(ID);
} catch (SQLException e) {
e.printStackTrace();
}
table = asker.giveTable();
scrollPane = new JScrollPane(tabel);
}
public static void main(String[] args){
AppWindow window = new AppWindow("Name", 2);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == newBook){
new BookAdded(ID);
panel.revalidate();
panel.add(scrollPane);
panel.repaint();
repaint();
}
}
}
Not the best method, but it will get you across the line...
public AppWindow(String user, int ID) {
this.ID = ID;
this.user = user;
setSize(500, 500);
setTitle("Books");
setLayout(new BorderLayout());
greetText.setText("Hi "+user+" here are your books:");
add(greetText, BorderLayout.NORTH);
JTable table = askData();
scrollPane.setViewportView(table);
panel.add(scrollPane);
add(panel, BorderLayout.CENTER);
panel2.add(newBook);
panel2.add(deleteBook);
panel2.add(changeBook);
add(paneel2, BorderLayout.SOUTH);
newBook.addActionListener(this);
setVisible(true);
}
private JTable askData() {
DataAsker asker = null;
try {
asker = new AndmeKysija(ID);
} catch (SQLException e) {
e.printStackTrace();
}
return asker.giveTable();
}
public static void main(String[] args){
AppWindow window = new AppWindow("Name", 2);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == newBook){
new BookAdded(ID);
JTable table = askData();
scrollPane.setViewportView(table);
}
}
What you should be doing is creating a new TableModel from the results of AndmeKysija, AndmeKysija should have idea or concept of the UI. You would then simply need to use JTable#setModel to update the view...
Swing uses a varient of the Model-View-Controller paradigm
Related
public class BillDetailsPanel implements ActionListener {
JPanel panel;
int flag = 0;
JLabel lItemName, lPrice, lQty, ltax, lDisPrice;
JTextField price, qty, tax, disPrice;
JComboBox<String> itemName;
String[] bookTitles = new String[] { "Effective Java", "Head First Java",
"Thinking in Java", "Java for Dummies" };
JButton addBtn
public BillDetailsPanel() {
panel = new JPanel();
panel.setPreferredSize(new Dimension(900, 50));
FlowLayout layout = new FlowLayout(FlowLayout.CENTER, 5, 15);
panel.setLayout(layout);
// panel.setBackground(Color.GREEN);
lItemName = new JLabel("Item Name");
lPrice = new JLabel("Price");
lQty = new JLabel("Quantity");
ltax = new JLabel("Tax");
lDisPrice = new JLabel("Discount Price");
itemName = new JComboBox<String>(bookTitles);
itemName.addActionListener(this);
price = new JTextField(8);
// price.setEditable(false);
qty = new JTextField(4);
tax = new JTextField(5);
// tax.setEditable(false);
disPrice = new JTextField(8);
addBtn = new JButton("Add");
addBtn.addActionListener(this);
panel.add(lItemName);
panel.add(itemName);
panel.add(lPrice);
panel.add(price);
panel.add(lQty);
panel.add(qty);
panel.add(ltax);
panel.add(tax);
panel.add(lDisPrice);
panel.add(disPrice);
panel.add(addBtn);
panel.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
BillTablePanel btp=new BillTablePanel();
String[] data=new String[5];
data[0]=(String) itemName.getSelectedItem();
data[1]=price.getText();
data[2]=qty.getText();
data[3]=tax.getText();
data[4]=qty.getText();
btp.model.addRow(data);
btp.model.addRow(data);
System.out.println(data+"dataaaaaaaaaaaa");
}
}
}
public class BillTablePanel implements ActionListener{
public JPanel panel;
public JTable table;
public JScrollPane scrollPane, scrollPane1;
public DefaultTableModel model;
public int a=10;
String[] data=new String[5];
public BillTablePanel () {
panel = new JPanel();
panel.setLayout(null);
model = new DefaultTableModel();
String columnNames[] = { "Item Name", "Actual Price", "Qty", "Tax",
"Price" };
table = new JTable();
model.setColumnIdentifiers(columnNames);
table.setModel(model);
table.setFocusable(false);
scrollPane = new JScrollPane(table);
scrollPane.setBounds(0, 0, 850, 100);
panel.add(scrollPane);
}
<br>
public class TestClassFrame {
JFrame f;
BillDetailsPanel bill = new BillDetailsPanel();
BillTablePanel billTablePanel = new BillTablePanel();
public TestClassFrame() {
f = new JFrame("Zeon Systems");
f.setLayout(null);
bill.panel.setBounds(0, 0, 900, 100);
f.add(bill.panel);
billTablePanel.panel.setBounds(0, 100, 900, 500);
f.add(billTablePanel.panel);
f.pack();
f.setSize(900, 550);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestClassFrame();
}
}
Problem with this code is The class Bill detais contain some text boxes and a button The BillTablepane class contain a Jtable I want to add the items from BillDetaisaPanel to the Jtable
On clicking the Jbutton which is not showing any error but the values are not inserting on it
The Full source is there Somebody please help me to find the logical error,
In your actionPerformed method, you're creating a new BillTablePanel object, at line (1), and then trying to add to the table model on line (2):
public void actionPerformed(ActionEvent e) {
BillTablePanel btp=new BillTablePanel(); // **** (1)
// ...
btp.model.addRow(data); // ***** (2)
But understand that that new BillTablePanel is just that, a completely new and distinct object, one completely unrelated to the one that is displayed. To change the state of the displayed data, you must call methods on the displayed BillTablePanel object, not on a new one that you create just for the actionPerformed method.
For example, here's a similar minimal program:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class TableExample extends JPanel {
private HoldsTable holdsTable = new HoldsTable();
private JTextField lastNameField = new JTextField(10);
private JTextField firstNameField = new JTextField(10);
public TableExample() {
JPanel fieldPanel = new JPanel();
fieldPanel.add(new JLabel("Last Name:"));
fieldPanel.add(lastNameField);
fieldPanel.add(new JLabel("First Name:"));
fieldPanel.add(firstNameField);
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new AbstractAction("Your Action") {
#Override
public void actionPerformed(ActionEvent evt) {
HoldsTable ht = new HoldsTable(); // creates a new reference -- bad!
String lastName = lastNameField.getText();
String firstName = firstNameField.getText();
ht.addName(lastName, firstName);
}
}));
buttonPanel.add(new JButton(new AbstractAction("My Action") {
#Override
public void actionPerformed(ActionEvent evt) {
// HoldsTable ht = new HoldsTable();
String lastName = lastNameField.getText();
String firstName = firstNameField.getText();
// ht.addName(lastName, firstName);
holdsTable.addName(lastName, firstName); // use the ref to the displayed object
}
}));
setLayout(new BorderLayout());
add(holdsTable, BorderLayout.CENTER);
add(fieldPanel, BorderLayout.PAGE_START);
add(buttonPanel, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
TableExample mainPanel = new TableExample();
JFrame frame = new JFrame("TableExample");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class HoldsTable extends JPanel {
private static final String[] COL_NAMES = { "Last Name", "First Name" };
private DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0);
private JTable table = new JTable(model);
public HoldsTable() {
setLayout(new BorderLayout());
add(new JScrollPane(table));
}
public void addName(String lastName, String firstName) {
String[] row = { lastName, firstName };
model.addRow(row);
}
}
Your program creates a new non-displayed object, and changes its properties, similar to this code in my program above:
#Override
public void actionPerformed(ActionEvent evt) {
HoldsTable ht = new HoldsTable(); // creates a new reference --
// bad!
String lastName = lastNameField.getText();
String firstName = firstNameField.getText();
ht.addName(lastName, firstName);
}
}));
But since the object whose state is being changed, here ht, but in your code its btp, is not the one that is displayed, nothing will show.
The correct way is shown in the other action:
#Override
public void actionPerformed(ActionEvent evt) {
// HoldsTable ht = new HoldsTable();
String lastName = lastNameField.getText();
String firstName = firstNameField.getText();
// ht.addName(lastName, firstName);
holdsTable.addName(lastName, firstName); // use the ref to the
// displayed object
}
I create a field of the GUI view that holds the JTable, here holdsTable and call a method on it. Since holdsTable is visible, changes in its state will be shown in the program (here the JTable).
I have a list and I want each time when I select a value from the list, its index to be displayed into a JPanel. I must mention that when I print the index in the console it gets printed the right way, but in the JPanel I don't get anything. An very intresting that I noticed is that in first instance if I select a value nothing is displayed in the JPanel, but if I minimize the frame and then maximize it back the index is displayed in the panel.
Any explanations for this strange behaviour?
public class Start extends JFrame {
private static JPanel leftPanel = new JPanel();
private static JPanel rightPanel = new JPanel();
private JList leftList = new JList();
private DefaultListModel<String> listModel = new DefaultListModel<String>();
private static JScrollPane listScrollPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new Start();
JFrame frame = new JFrame();
frame.add(leftPanel,BorderLayout.EAST);
frame.add(listScrollPane,BorderLayout.WEST);
frame.add(rightPanel);
frame.setTitle("Example");
frame.setSize(600,400);
frame.setLocation(200,100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Start() {
leftPanel.setLayout(new BoxLayout(leftPanel,BoxLayout.PAGE_AXIS));
leftList = new JList(listModel);
leftList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
listScrollPane = new JScrollPane(leftList);
listScrollPane.setBorder(BorderFactory.createTitledBorder("Proteins"));
rightPanel.setBackground(Color.cyan);
rightPanel.setLayout(new FlowLayout());
for (String name : allNames) {
listModel.addElement(name);
}
leftList.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent event) {
if(!event.getValueIsAdjusting()) {
int indexndex = leftList.getSelectedIndex();
JLabel lbl = new JLabel();
lbl.setText("index = " + index);
rightPanel.add(lbl);
System.out.println(index);
}
}
});
}
}
This questions has been asked a few times but mine is a little different. I created a small application and in the view I added a few JPanels to a JFrame. I then try to add actionListeners in the controller which is where the problem happened.
The code below gives me the following error:
The method addActionListener(new ActionListener(){})
is undefined for the type JPanel
The view class
public class MainMenuGUI {
JTabbedPane tabbedPane = new JTabbedPane();
JPanel findUserPanel;
JPanel deleteUserPanel;
JPanel addUserPanel;
JFrame frame = new JFrame();
JPanel tabbedPanel = new JPanel();
//Controller class for tabbedPanel
ControllerTabbedPane listen = new ControllerTabbedPane(this);
//Controller class for findUserPanel
FindUserPanelController findUserController = new FindUserPanelController(findUserPanel);
public MainMenuGUI() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
findUserPanel = createFindUserPanel();
deleteUserPanel = createDeleteUserPanel();
addUserPanel = createAddUserPanel();
tabbedPane.addTab("Find User", findUserPanel);
tabbedPane.addTab("Delete User", deleteUserPanel);
tabbedPane.addTab("Add User", addUserPanel);
tabbedPanel.add(tabbedPane);
frame.add(tabbedPanel);
frame.pack();
// opens frame in the center of the screen
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
JPanel createFindUserPanel() {
findUserPanel = new JPanel();
findUserPanel.setPreferredSize(new Dimension(300, 300));
findUserPanel.setLayout(new GridLayout(5, 7));
JLabel firstlbl = new JLabel("First Name");
JLabel lastlbl = new JLabel("Last Name");
JLabel addresslbl = new JLabel("Address");
JLabel agelbl = new JLabel("Age");
JTextField firstNametxt = new JTextField(15);
JTextField lastNametxt = new JTextField(15);
JTextField addresstxt = new JTextField(30);
JTextField age = new JTextField(3);
JButton btn = new JButton("Submit");
JScrollPane window = new JScrollPane();
window.setViewportBorder(new LineBorder(Color.RED));
window.setPreferredSize(new Dimension(150, 150));
findUserPanel.add(firstlbl);
findUserPanel.add(firstNametxt);
findUserPanel.add(lastlbl);
findUserPanel.add(lastNametxt);
findUserPanel.add(addresslbl);
findUserPanel.add(addresstxt);
findUserPanel.add(agelbl);
findUserPanel.add(age);
findUserPanel.add(window, BorderLayout.CENTER);
findUserPanel.add(btn);
return findUserPanel;
}
Controller Class
public class ControllerTabbedPane {
MainMenuGUI mainMenuGUI;
int currentTabbedIndex = 0;
ControllerTabbedPane(MainMenuGUI mainMenuGUI){
this.mainMenuGUI = mainMenuGUI;
addTabbedPaneListeners();
}
private void addTabbedPaneListeners() {
mainMenuGUI.tabbedPane.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent ce) {
currentTabbedIndex = mainMenuGUI.tabbedPane.getSelectedIndex();
System.out.println("Current tab is:" + currentTabbedIndex);
}
});
}
/*ERROR saying The method addActionListener(new ActionListener(){})
is undefined for the type JPanel*/
private void findPanelListeners() {
mainMenuGUI.findUserPanel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
});
}
This is the way to achieve your request:
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JButton bt1 = new JButton();
JButton bt2 = new JButton();
panel1.add(bt1);
panel2.add(bt2);
bt1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Bt1 on panel1 pressed");
}
});
bt2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Bt2 on panel2 pressed");
}
});
You can modify variables or other objects into the listeners to store which panel was "pressed".
I think its not possible to add addActionListner() to JPanel
Instead
You can use,
JPanel p1=new JPanel();
p1.addMouseListener(this);
And override
public void mouseClicked(MouseEvent me)
{
int x=me.getX();
int y=me.getY();
System.out.println(x+","+y);
//By using x AND y you can identify the panel
}
NB: extends MouseAdapter
I've been trying for days to access some variables from a class above in an ActionListener, but I fail all the time :( What am I doing wrong? I hope you can help me folks.
public class FileFrameBetterStructured extends JFrame {
protected FileModel fileModel = new FileModel();
{
// Set Preferences
setSize(500, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// Create table
FileModel fileModel = new FileModel();
JTable FileTable = new JTable(fileModel);
TableRowSorter<TableModel> TableRowSorter = new TableRowSorter<TableModel>(fileModel);
FileTable.setRowSorter(TableRowSorter);
FileTable.setColumnSelectionAllowed(true);
FileTable.setDefaultRenderer(Number.class, new BigRenderer(1000));
JScrollPane JScrollPane = new JScrollPane(FileTable);
getContentPane().add(JScrollPane, BorderLayout.CENTER);
// Create textfilter
JPanel panel = new JPanel(new BorderLayout());
JLabel label = new JLabel("Filter");
panel.add(label, BorderLayout.WEST);
final JTextField filterText = new JTextField("");
panel.add(filterText, BorderLayout.CENTER);
add(panel, BorderLayout.NORTH);
JButton button = new JButton("Filter");
add(button, BorderLayout.SOUTH);
setSize(300, 250);
setVisible(true);
}
public static void main(String args[]) {
final FileFrameBetterStructured FileFrame = new FileFrameBetterStructured();
// Integrate ActionListener for textfilter
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String text = filterText.getText();
if (text.length() == 0) {
TableRowSorter.setRowFilter(null);
} else {
TableRowSorter.setRowFilter(RowFilter.regexFilter(text));
}
}
});
}
}
In the ActionListener I want to access the variables: button, filterText and TableRowSorter. THANK YOU!
Add this to the top of your class:
protected static JButton button;
protected static JTextField filterText;
protected static TableRowSorter<TableModel> TableRowSorter;
Change your code as following
public class FileFrameBetterStructured extends JFrame {
static JButton button;
static JTextField filterText;
staitc TableRowSorter<TableModel> tableRowSorter;
protected FileModel fileModel = new FileModel();
FileFrameBetterStructured()
{
// Set Preferences
setSize(500, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// Create table
FileModel fileModel = new FileModel();
JTable FileTable = new JTable(fileModel);
tableRowSorter = new TableRowSorter<TableModel>(fileModel);
FileTable.setRowSorter(TableRowSorter);
FileTable.setColumnSelectionAllowed(true);
FileTable.setDefaultRenderer(Number.class, new BigRenderer(1000));
JScrollPane JScrollPane = new JScrollPane(FileTable);
getContentPane().add(JScrollPane, BorderLayout.CENTER);
// Create textfilter
JPanel panel = new JPanel(new BorderLayout());
JLabel label = new JLabel("Filter");
panel.add(label, BorderLayout.WEST);
filterText = new JTextField("");
panel.add(filterText, BorderLayout.CENTER);
add(panel, BorderLayout.NORTH);
button = new JButton("Filter");
add(button, BorderLayout.SOUTH);
setSize(300, 250);
setVisible(true);
}
public static void main(String args[]) {
final FileFrameBetterStructured FileFrame = new FileFrameBetterStructured();
// Integrate ActionListener for textfilter
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String text = filterText.getText();
if (text.length() == 0) {
TableRowSorter.setRowFilter(null);
} else {
TableRowSorter.setRowFilter(RowFilter.regexFilter(text));
}
}
});
}
}
Hope it helps.
My problem is that a JTable does not update when I select my combobox. The program I present below should delete all data (data = null;), when LA is selected. The table does not update.
public class minimumExample extends JFrame {
private JTabbedPane tabbedPane;
private FilteredTabPanel filteredTabPanel;
public void createTabBar() {
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
filteredTabPanel = new FilteredTabPanel();
tabbedPane.addTab("Test", filteredTabPanel.createLayout());
add(tabbedPane);
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
}
private void makeLayout() {
setTitle("Test App");
setLayout(new BorderLayout());
setPreferredSize(new Dimension(1000, 500));
createTabBar();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public void start() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
makeLayout();
}
});
}
public static void main(String[] args) throws IOException {
minimumExample ex = new minimumExample();
ex.start();
}
public class FilteredTabPanel extends JPanel {
private JPanel selectionArea;
private JLabel lCity;
private JComboBox cityBox;
private JTable filterTable;
String[] columnNames = {"Cities"};
String[][] data = {
{"NY"}, {"NY"}, {"NY"}, {"NY"}, {"LA"}, {"LA"},{"Columbia"},{"DC"},{"DC"},{"DC"},{"DC"},{"DC"},{"DC"}
};
private JScrollPane scrollPane;
public JPanel createLayout() {
JPanel panel = new JPanel(new GridLayout(0, 1));
//add panels to the layout
panel.add(addButtons());
panel.add(showTable());
repaint();
revalidate();
return panel;
}
public JPanel addButtons(){
selectionArea = new JPanel(new FlowLayout(FlowLayout.LEFT));
lCity = new JLabel("City");
String[] fillings = {"NY", "LA", "Columbia", "DC"};
cityBox = new JComboBox(fillings);
cityBox.addActionListener(new ActionListener() {
private String cityFilter;
#Override
public void actionPerformed(ActionEvent arg0) {
//2. get data
cityFilter = cityBox.getSelectedItem().toString();
if(cityFilter.equals("LA")) {
data = null;
}
showTable();
repaint();
}
});
selectionArea.add(lCity);
selectionArea.add(cityBox);
selectionArea.repaint();
return selectionArea;
}
private JScrollPane showTable() {
filterTable =new JTable(data, columnNames);
filterTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
scrollPane = new JScrollPane(filterTable);
scrollPane.repaint();
scrollPane.validate();
return scrollPane;
}
}
}
As you can see the table does not update. Any recommendations what I am doing wrong?
Instead of creating new instance of you objects by calling showTable (which never get added to the screen in any way), which is just going to completely mess up your object references, try resetting the TableModel, for example...
if ("LA".equals(cityFilter)) {
filterTable.setModel(new DefaultTableModel(null, columnNames));
}
Take a closer look at How to Use Tables for more details