I have a JTable which contains a list of item and a JPanel with some components. When I click to my button, I want all information of the selected item in the JTable will be loaded to the JPanel. At the first time, it work well but at the further times when I click to my button the Jpanel appears with empty component.
The code when clicking to my button:
jbtUpdateContract.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
Object contractID = getValueOfSelectedRow(contractTable, 0);
Contract contract = contractTransaction.getContractByID(Integer.parseInt(contractID.toString()));
//Create Jpanel to display information
jplUpdateContractForm.removeAll();
jplUpdateContractForm = createContractForm(contract);
jplUpdateContractForm.revalidate();
//Modify contract frame
jfrmUpdateContract.getContentPane().add(jplUpdateContractForm,
BorderLayout.CENTER);
jfrmUpdateContract.setSize(400, 300);
jfrmUpdateContract.setVisible(true);
jfrmUpdateContract.setResizable(false);
}
});
And my createContractForm function:
public static JPanel createContractForm(Contract contract)
{
JPanel jplContractForm = new JPanel(new SpringLayout());
JLabel jlblAppointmentDate = new JLabel("Appointment date:", JLabel.TRAILING);
jlblAppointmentDate.setName("jlblAppointmentDate");
jplContractForm.add(jlblAppointmentDate);
final JTextField jtxtAppointmentDate = new JTextField(15);
jtxtAppointmentDate.setName("jtxtAppointmentDate");
jtxtAppointmentDate.setText(contract.getAppointmentDate());
jtxtAppointmentDate.setEditable(false);
jtxtAppointmentDate.addMouseListener(appointmentDateMouseListener(jtxtAppointmentDate));
jlblAppointmentDate.setLabelFor(jtxtAppointmentDate);
jplContractForm.add(jtxtAppointmentDate);
jplContractForm.setOpaque(true);
//***Customer Cobobox
JLabel jlblCustomer= new JLabel("Customer:", JLabel.TRAILING);
jlblCustomer.setName("jlblCustomer");
jplContractForm.add(jlblCustomer);
final JComboBox jcbxCustomer = new JComboBox();
jcbxCustomer.setName("jcbxCustomer");
//Load customers from DB to combobox
Customer[] customers = customerTransaction.getAllCustomer();
for(int i = 0; i < customers.length; i++)
jcbxCustomer.addItem(customers[i]);
System.out.println("----------CUSTOMER----------" + getIndexOfCustomerComboBoxItem(jcbxCustomer, contract.getCustomerSeq()));
jcbxCustomer.setSelectedIndex(getIndexOfCustomerComboBoxItem(jcbxCustomer, contract.getCustomerSeq()));
jlblCustomer.setLabelFor(jcbxCustomer);
jplContractForm.add(jcbxCustomer);
jplContractForm.setOpaque(true);
}
Please help me to explaint why the JPanel is empty as I describes above.
Regards.
The frame is already visible, so I don't think any of these lines of code will help.
jfrmUpdateContract.setSize(400, 300);
jfrmUpdateContract.setVisible(true);
jfrmUpdateContract.setResizable(false);
The revalidate() does nothing because you haven't added the panel to the frame yet. Try the revalidate() AFTER the panel has been added to the frame.
jplUpdateContractForm = createContractForm(contract);
//jplUpdateContractForm.revalidate();
jfrmUpdateContract.getContentPane().add(jplUpdateContractForm, BorderLayout.CENTER);
jplUpdateContractForm.revalidate();
If you need more help then post a proper SSCCE.
Related
I have a class that extends JFrame and works by adding in 2 panels with BoxLayout buttons, and one JTabbedPane in the center which displays graphs.
I want one of the buttons to remove all current components in the frame and add new ones.
Here are the methods used.
private void createAndShowGraphs() {
ImageIcon createImageIcon(lsuLettersPath); //simple png file to fill one tab
final JTabbedPane jtp = new JTabbedPane();
JLabel iconLabel = new JLabel();
iconLabel.setOpaque(true);
jtp.addTab(null, icon, iconLabel);
//Here is where the errors begin
JPanel menu = new JPanel();
menu.setLayout(new BoxLayout(menu, BoxLayout.Y_AXIS));
//I want this button to remove all components currently in the JFrame and replace them with new components specified in the createAndShowIntro() method
menu.add(new JButton(new AbstractAction("Intro Pane") {
public void actionPerformed(ActionEvent e) {
//I've also tried putting removeAll in the Intro method
removeAll();
createAndShowIntro();
}
}));
add(jtp, BorderLayout.CENTER);
add(menu, BorderLayout.WEST);
pack();
setVisible(true);
}
private void createAndShowIntro() {
System.out.println("Made it to Intro");
//all I want is a blank JLabel with the String "test" to show up
JPanel test = new JPanel();
test.setLayout(new BorderLayout());
JLabel label = new JLabel();
label.setText("test");
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setVerticalAlignment(SwingConstants.CENTER);
test.add(label);
add(test, BorderLayout.CENTER);
test.revalidate();
label.revalidate();
validate();
test.repaint();
label.repaint();
repaint();
pack();
setVisible(true);
}
When I call createAndShowGraphs() in main() and then hit the 'Intro' button, everything freezes and nothing is actually removed. I know it makes it the Intro method because of the "Made it to Intro" string output to the terminal.
I've tried all kinds of combinations of invalidate(), validate(), revalidate(), repaint() on the labels and on the frame itself. Really frustrated because I don't know how else I'm going to be able to display 3 different screens to switch back and forth between while only actually displaying one at a time.
Thanks for your time.
I'm creating a program that features a grid of 12 JPanels. When the "add image" button is pressed, an image appears in the first JPanel in the grid and a counter is incremented by one. From then onwards, every time the "add image" is clicked again, an image would be added to the next JPanel. For some reason, the button only adds an image to the first JPanel and then stops working. Here's the code I've got so far.
public class ImageGrid extends JFrame {
static JPanel[] imageSpaces = new JPanel[12];
int imageCounter = 0;
ImageGrid() {
this.setTitle("Image Grid");
setSize(750, 750);
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel p3 = new JPanel();
p3.setLayout(new GridLayout(3, 4, 10, 5));
p3.setBackground(Color.WHITE);
p3.setOpaque(true);
p3.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
for (int j = 0; j < imageSpaces.length; j++) {
imageSpaces[j] = setImageSpace();
p3.add(imageSpaces[j]);
}
MyButtonPanel p1 = new MyButtonPanel();
add(p1, BorderLayout.SOUTH);
add(p3, BorderLayout.CENTER);
}
public JPanel setImageSpace() {
JPanel test;
test = new JPanel();
test.setOpaque(true);
test.setPreferredSize(new Dimension(100, 100));
return test;
}
class MyButtonPanel extends JPanel implements ActionListener {
final JButton addImage = new JButton("Add Image");
ImageIcon lorryPicture = new ImageIcon(ImageGrid.class.getResource("/resources/lorry.png"));
JLabel lorryImage = new JLabel(lorryPicture);
MyButtonPanel() {
add(addImage);
addImage.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == addImage) {
imageSpaces[imageCounter].add(lorryImage);
revalidate();
repaint();
imageCounter++;
}
}
}
public static void main(String[] args) {
ImageGrid test = new ImageGrid();
test.setVisible(true);
}
}
You should be revalidating and repainting the panel, (which is the containter being affected by the addition), not the frame
imageSpaces[imageCounter].add(lorryImage);
imageSpaces[imageCounter].revalidate();
imageSpaces[imageCounter].repaint();
Diclaimer: This may work as a simple fix, but also note that a component (in this case your JLabel lorryImage) can only have one parent container. The reason the above fix still works is because you don't revalidate and repaint the previous panel, the label was added to. So you may want to think about doing it correctly, and adding a new JLabel to each panel.
if (e.getSource() == addImage) {
JLabel lorryImage = new JLabel(lorryPicture);
imageSpaces[imageCounter].add(lorryImage);
imageSpaces[imageCounter].revalidate();
imageSpaces[imageCounter].repaint();
imageCounter++;
}
Disclaimer 2: You should add a check, to only add a label if the count is less than the array length, as to avoid the ArrayIndexOutOfBoundsException
Side Notes
Swing apps should be run from the Event Dispatch Thread (EDT). You can do this by wrapping the code in the main in a SwingUtilities.invokeLater(...). See more at Initial Threads
You could also just use a JLabel and call setIcon, instead of using a JPanel
I have a JPanel to which when a button is pressed I want to add a new JLabel and JTextField too. However, I can't seem to get it working.
Is there an issue with my ActionListener, and if not, how could this be achieved?
JPanel south = new JPanel();
JButton add = new JButton("Add");
ActionListener addListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JLabel mL = new JLabel("MOD: ");
mR.add(mL);
JTextField mM = new JTextField(10);
mR.add(mM);
mR.repaint();
}
};
add.addActionListener(addListener);
south.add(add);
add(south, BorderLayout.NORTH);
The layout of the mR panel is a grid layout set to allow multiple rows and two columns.
Call mR.revalidate() before repaint();
See my answer on a previous SO question for some sample code which dynamically adds a component to a container
I have a JComboBox, and I want to load in a JScrollPane a different content everytime I choose a different element from the JComboBox. The content consists of a various number of JLabels and JTextFields.
What I have done:
JScrollPane scrollPane;
JComboBox combo;
JPanel back = new JPanel(new BorderLayout());
combo = new JComboBox({ "Bird", "Cat", "Dog", "Rabbit", "Pig" });
combo.addActionListener(new AnimalLoader());
scrollPane = showPanel((String) combo.getSelectedItem());
back.add(combo, BorderLayout.NORTH);
back.add(scrollPane, BorderLayout.SOUTH);
back.setVisible(true);
protected JScrollPane showPanel(String name)
{
JPanel contentPanel = new JPanel(new JLabel(name));
scrollPane = new JScrollPane(contentPanel);
return scrollPane;
}
private class AnimalLoader implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JComboBox cb = (JComboBox) e.getSource();
String selected = (String) cb.getSelectedItem();
scrollPane = showPanel(selected);
}
}
I didn't manage to make this reload a different JScrollPane when I choose another item.
Only the JScrollPane that belongs to the first item (the default one) of the JComboBox is loaded.
Any ideas of what I've done wrong please?
scrollPane = showPanel(selected);
Don't create a new scoll pane when you select an item. Instead you need to change the panel that is contained in the viewport of the scroll pane. That is, your "showPanel" method should return the panel, not a scrollpane. Then you can use:
scrollPane.setViewportView( showPanel(selected) );
Next time a proper SSCCE should be posted.
There is no evidence the newly created JScrollPane is ever added to anything.
I would try either of:
Add a JPanel with a CardLayout to
the JScrollPane, and add other
collections of components to the
JPanel.
Call
setViewportView(Component view) on
the existing JScrollPane.
panel.revalidate();
panel.repaint();
As you are using this example, try this variation at line 73, near the end of the ComboBoxDemo constructor:
//Lay out the demo.
add(petList, BorderLayout.PAGE_START);
JScrollPane jsp = new JScrollPane(picture);
jsp.getViewport().setPreferredSize(new Dimension(100, 100));
add(jsp, BorderLayout.PAGE_END);
setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
I want to repeatedly take input from the user(probably using a button) via a JOptionPane(already done) and store the details in something(how about a dynamic object array) and display this information as a list in a scrollable JList.
MY CODE
import java.awt.GridLayout;
import javax.swing.*;
class Flight {
public static void main(String[] args) {
//Panel
JPanel panel = new JPanel(new GridLayout(7, 2,20, 20));
//Add textfields here
JTextField txtflightno = new JTextField(8);
JTextField txtmechanicalstatus = new JTextField(8);
JTextField txtmedicalstatus = new JTextField(8);
JTextField txtfuellevel = new JTextField(8);
JTextField txtweathercondition = new JTextField(8);
JTextField txtfrequency = new JTextField(8);
JTextField txtflightpath = new JTextField(8);
//Add labels here
JLabel lblflightno = new JLabel("Flight No : ");
JLabel lblmechanicalstatus = new JLabel("Mechanical Status:");
JLabel lblmedicalstatus = new JLabel("Medical Status:");
JLabel lblfuellevel = new JLabel("Fuel Level:");
JLabel lblweathercondition = new JLabel("Weather Condition:");
JLabel lblfrequency = new JLabel("Frequency:");
JLabel lblflightpath = new JLabel("Flight Path:");
//Adding flightno to panel
panel.add(lblflightno);
panel.add(txtflightno);
//Adding mechanicalstatus to the panel
panel.add(lblmechanicalstatus);
panel.add(txtmechanicalstatus);
//Adding medicalstatus to the panel
panel.add(lblmedicalstatus);
panel.add(txtmedicalstatus);
//Adding fuellevel to the panel
panel.add(lblfuellevel);
panel.add(txtfuellevel);
//Adding weathercondition to the panel
panel.add(lblweathercondition);
panel.add(txtweathercondition);
//Adding frequency to the panel
panel.add(lblfrequency);
panel.add(txtfrequency);
//Adding flightpath to the panel
panel.add(lblflightpath);
panel.add(txtflightpath);
panel.setBounds(0, 0, 800, 600);
int result = JOptionPane.showConfirmDialog(null, panel, "Flight Details",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
}
}
}
How must I do the storing of the plane details ? How must I implement a scrollable JList ? Any suggestions.
Many Thanks
As discussed in How to Use Lists, JList uses a list model as the source of data it displays. Just add your data to a DefaultListModel, and use it to construct your list.
DefaultListModel dlm = new DefaultListModel();
// add data
JList list = new JList(dlm);
panel.add(new JScrollPane(list));
To make the JList scrollable, simply embed it in a JScrollPane. Instead of
add(myList, constraints);
do
add(new JScrollPane(myList), constraints);
To extend the list, just get the JList's ListModel (using getListModel) and use add to add objects.
More on using ListModels in Sun's tutorial.
More on ScrollPane in the Tutorial, too.
You've to use the ActionListener of Button, that you've missed in the code snippet.
In the OK Option :
JList jlist = ...;
jlist.add(txtflightno.getText());
jlist.add(txtmechanicalstatus.getText());
jlist.add(txtmedicalstatus.getText());
....
....
&
add(new JScrollPanel(myList), constraints);
After this use validate method of Component to update the list with this new item.
But one thing you should remember is that list displays each item row-wise.
I suggest you to use JTable with which you can display your items in a meaningful way...