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
Related
I have my MainWindow class where menue buttons and everything else are. In the middle of it is an Panel called content. I want to load JPanels from other classes into this field. But when i start the code below nothing shows up.
MainWindow Class:
public class MainWindow {
private JFrame frame;
private JScrollPane Content;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow window = new MainWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MainWindow() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane scrollPane = new JScrollPane();
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
JPanel TopPanel = new JPanel();
scrollPane.setColumnHeaderView(TopPanel);
JLabel lblNewLabel = new JLabel("Made by " + Globals.Author);
TopPanel.add(lblNewLabel);
JButton btnHome = new JButton("Home");
TopPanel.add(btnHome);
btnHome.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
Content.add(new Home());
}
});
Content = new JScrollPane();
scrollPane.setViewportView(Content);
}
}
JPanel Class:
public class Home extends JPanelContentTemplate {
/**
* Create the panel.
*/
protected void InitializeComponents(){
setLayout(new BorderLayout(0, 0));
JPanel OptionsMenuePanel = new JPanel();
add(OptionsMenuePanel, BorderLayout.WEST);
JPanel ConentPanel = new JPanel();
add(ConentPanel, BorderLayout.CENTER);
ConentPanel.setLayout(new GridLayout(1, 2, 0, 0));
JLabel lblConnectedWith = new JLabel("Connected With:");
ConentPanel.add(lblConnectedWith);
JTextPane textServerIP = new JTextPane();
ConentPanel.add(textServerIP);
}
#Override
protected void Refresh() {
// TODO Auto-generated method stub
}
}
The InitializeComponents method comes from an Self Created Superclass:
public abstract class JPanelContentTemplate extends JPanel {
/**
* Create the panel.
*/
public JPanelContentTemplate() {
InitializeComponents();
}
protected abstract void InitializeComponents();
protected abstract void Refresh();
}
I also tried an repaint etc.
Thanks for Help
Nothing shows up because you add nothing but empty JScrollPanes to your GUI:
Content = new JScrollPane();
scrollPane.setViewportView(Content);
Here is a simple example of adding separate panels to the MainFrame. I hope it helps you.
public class SidePanel extends JPanel {
private JLabel label;
public SidePanel() {
setBorder(BorderFactory.createEtchedBorder());
label = new JLabel("Hello");
setVisible(true);
/* More Code Goes Here */
}
}
public class CenterPanel extends JPanel {
/* Center Panel Code */
}
public class MainFrame extends JFrame {
private SidePanel sidePanel;
private CenterPanel centerPanel;
public MainFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
sidePanel = new SidePanel();
centerPanel = new CenterPanel();
add(sidePanel, BorderLayout.WEST);
add(centerPanel, BorderLayout.CENTER);
setSize(300, 300);
setVisible(true);
}
}
/* Main App */
public static void main(String [] args) {
try {
/* Lambda Expression */
SwingUtitlities.InvokeLater(() -> new MainFrame());
} catch(Exception ex) {
ex.printStackTrace();
}
}
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);
}
}
});
}
}
When I compile, I have a blank window. No elements are being added to the main frame. What am I missing?
public class Gui extends JFrame {
private JComboBox<String> box;
private JLabel picture;
private static String[] filename = {"pic1", "pic2.png" };
private Icon[] pics = { new ImageIcon(getClass().getResource(filename[0])),
new ImageIcon(getClass().getResource(filename[1])) };
Gui() {
super("window");
setLayout(new FlowLayout());
setVisible(true);
setSize(600, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
box = new JComboBox<String>(filename);
box.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
picture.setIcon(pics[box.getSelectedIndex()]);
}
}
});
picture = new JLabel(pics[0]);
add(picture);
add(box);
}
}
Possible problems:
1. Make sure the relative or absolute path used for pictures is correct.
2. Where you create an object of this class, you need to call t.setVisible(true). (i.e., have a look at my main method)
public class Gui extends JFrame {
private JComboBox<String> box;
private JLabel picture;
private static String[] filename = {"C:\\Users\\..\\pic1.jpg","C\\Users\\..\\pic2.jpg" };
private Icon[] pics = { new ImageIcon(filename[0]),
new ImageIcon(filename[1] ) };
Gui() {
super("window");
setLayout(new FlowLayout());
setVisible(true);
setSize(600, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
box = new JComboBox<String>(filename);
box.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
picture.setIcon(pics[box.getSelectedIndex()]);
}
}
});
picture = new JLabel(pics[0]);
add(picture);
add(box);
}
public static void main(String[] args){
Gui t = new Gui();
t.setVisible(true);
}
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
We have a controller where we have a pre-declared JList and JLabel that we are adding to a JPanel. Outside of the initial layout/adding code I can update a JLabel (e.g. change its text) but I can't change the selection of the JList (e.g. jlist.setSelection(index) ) where it will update the UI. Code Below:
public class Test {
private JPanel myPanel;
private JList myList;
private JLabel myLabel;
public Test() {
//Some init code here...
this.myPanel = new JPanel();
this.myPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
String[] values = {"Value1", "Value2", "Value3", "Value4"}; //etc. etc.
this.myList = new JList(values);
this.myPanel.add(this.myList, gbc); //Add to panel
this.myLabel = new JLabel("Label1");
this.myPanel.add(this.myLabel, gbc); //Add to panel
//Add some code here to add it to a frame or something to display
}
public void updateLabel(String workingNewLabel) {
//The following works...
this.myLabel.setText(workingNewLabel);
// as in the label component in the JPanel will
//now be updated to the new value of workingNewLabel
}
public void changeSelectionInListToSomeIndex(int nonWorkingNewIndex) {
//The following does NOT update the JList in the panel...
//the selection remains whatever it was last set to.
this.myList.setSelectedIndex(nonWorkingNewIndex);
}
}
I've been able to get around this by iterating through all the components in myPanel looking for the JList component then set it to to myList eg.
//Code that goes after the line this.myPanel.add(this.myList, gbc);
for(Component component : this.myPanel.getComponents() ) {
//Iterate through it all until...
if (component.getClass() == this.myList.getClass()) {
this.myList = (JList) component; //cast the component as JList
}
}
Why do I need to do this for a JList but not for the JLabel? This is a workaround but it seems extremely hack-ish.
Thanks in advance!
-Daniel
#JB's right. Here's a working sscce:
/** #see http://stackoverflow.com/q/9540263/230513 */
public class Test {
private static Test test = new Test();
private JPanel myPanel;
private JList myList;
private JLabel myLabel;
public Test() {
myPanel = new JPanel();
myPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
String[] values = {"Value1", "Value2", "Value3", "Value4"};
myList = new JList(values);
myPanel.add(this.myList, gbc);
myLabel = new JLabel("Label1");
myPanel.add(this.myLabel, gbc);
myPanel.add(new JButton(new AbstractAction("Select Value3") {
#Override
public void actionPerformed(ActionEvent e) {
test.updateList(2);
}
}));
}
public void updateLabel(String label) {
myLabel.setText(label);
}
public void updateList(int index) {
myList.setSelectedIndex(index);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(test.myPanel);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
});
}
}