First, let me point out that I'm new to programming Java Desktop GUI's. I have created a desktop pane that can hold multiple JInternalFrames. For now, each JinternalFrame contains the same GUI components and a new jInternalFrame (Herein referred to as Internal Frame) can be created via a menu item click.
The elements on each internal Frame are as follows: 3 Jlabels, 3 JTextFields, a Jbutton and a Jtable. After rendering the first Internal Frame I populate the 3 text fields with information and then click the button and a new row is added to the table. The row contains the information used to populate the text fields.
Opening a second Internal Frame gives me, visually, the exact interface of the first. I populate this frame in the same manner,click the button and voila, the table in the second frame is populated.
The issue arises when I return to the previous internal frame. I can type into the text fields without issue but clicking the button to populate the table causes the table in the second Internal Frame to be populated. I suspect that I'm sharing a datamodel but am uncertain as to how to create distinct datamodels for jInternalFrame jTables when the GUI for each frame is the same.
Below is the code (as I am new to Java Desktop GUI development I followed one of the Oracle How-To's to render the internal Frame itself - very simple example):
public class InternalFrames extends JFrame
implements ActionListener {
private static final long serialVersionUID = 1L;
JDesktopPane desktop;
JLabel label1;
JLabel label2;
JLabel label3;
JLabel label4;
JTextField text1;
JTextField text2;
JTextField text3;
JTable table1;
public InternalFrames(){
super("Practice Internal Frames");
int inset = 50;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(inset,inset,screenSize.width - (inset*2),screenSize.height - (inset*2));
desktop = new JDesktopPane();
createFrame();
setContentPane(desktop);
setJMenuBar(setMenuBar());
}
protected JMenuBar setMenuBar(){
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Document");
menu.setMnemonic(KeyEvent.VK_D);
menuBar.add(menu);
JMenuItem menuItem = new JMenuItem("New");
menuItem.setMnemonic(KeyEvent.VK_N);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, ActionEvent.ALT_MASK));
menuItem.setActionCommand("New");
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Quit");
menuItem.setMnemonic(KeyEvent.VK_Q);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.ALT_MASK));
menuItem.setActionCommand("Quit");
menuItem.addActionListener(this);
menu.add(menuItem);
return menuBar;
}
public void actionPerformed(ActionEvent e){
if ("New".equals(e.getActionCommand())){
createFrame();
} else if ("Quit".equals(e.getActionCommand())){
}
}
protected void createFrame(){
InternalFrame internalFrame = new InternalFrame();
label1 = new JLabel("Name");
label2 = new JLabel("Email Address:");
label3 = new JLabel("Mobile Number:");
label4 = new JLabel("Test Frames");
label1.setSize(100,10);
label2.setSize(100,10);
label3.setSize(100,10);
label4.setSize(200,10);
text1 = new JTextField(40);
text2 = new JTextField(40);
text3 = new JTextField(40);
internalFrame.setLayout(new MigLayout());
internalFrame.getContentPane().add(label1);
internalFrame.getContentPane().add(text1, "wrap");
internalFrame.getContentPane().add(label2);
internalFrame.getContentPane().add(text2, "wrap");
internalFrame.getContentPane().add(label3);
internalFrame.getContentPane().add(text3,"wrap");
internalFrame.getContentPane().add(label4, "span 2, wrap");
internalFrame.getContentPane().add(new JScrollPane(createTable()), "span 2 2, wrap");
internalFrame.getContentPane().add(createButton());
internalFrame.setVisible(true);
desktop.add(internalFrame);
try {
internalFrame.setSelected(true);
} catch (java.beans.PropertyVetoException pve){ }
}
protected JTable createTable(){
DefaultTableModel dModel = new DefaultTableModel();
table1 = new JTable(dModel);
dModel.addColumn("Name");
dModel.addColumn("Email Address");
dModel.addColumn("Mobile Number");
return table1;
}
protected JButton createButton(){
JButton button1 = new JButton("Add New List Member");
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
System.out.println("You clicked the button");
populateTable(table1);
}
});
return button1;
}
protected void populateTable(JTable theTable){
if (validateEntry() == 0)
{
ListMembers listMember = new ListMembers();
listMember.setName(text1.getText());
listMember.setEmailAddress(text2.getText());
listMember.setMobilePhone(text3.getText());
Object[] data = {listMember.getName(),listMember.getEmailAddress(),listMember.getMobilePhone()};
DefaultTableModel dm = (DefaultTableModel) table1.getModel();
dm.addRow(data);
}
}
private static void createAndShowGUI(){
JFrame.setDefaultLookAndFeelDecorated(true);
InternalFrames internalFrame = new InternalFrames();
internalFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
internalFrame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Any help would be greatly appreciated.
Each time you create a new frame, you initialize a single field (table1) with this newly created table. And the listener of every button you create populates the table referenced by this unique table1 variable. The same goes for your text fields, etc.
Either only use local variables, and pass them between methods (for example, you need to pass the table you just created to the method creating the button, in order for this button to populate this table. Or you extract all the code to a new class, MyInternalFrame (choose a better name), make the table, textfields and buttons instance fields of this new class, and create a new instance of this MyInternalFrame class each time you need a new one.
This second solution looks like the best one to me.
Related
I am trying to figure out how to properly use listeners in this example. What I want it to do is display a pop-up after clicking the submit button showing what boxes are checked, but right now I get a popup after each box is clicked. I have tried implementing an action listener for the radio buttons and an item listener for the check boxes, but I'm not sure if this is the right thing to do. What am I missing?
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class CarSelector extends JFrame implements ActionListener, ItemListener{
JButton submit = new JButton("Submit");
JLabel label1 = new JLabel("Select Vehicle type and options");
JLabel carLabel = new JLabel("Vehicle Type");
JLabel options = new JLabel("Options");
ButtonGroup group = new ButtonGroup();
JRadioButton carRadio = new JRadioButton("Car", true);
JRadioButton vanRadio = new JRadioButton("Minivan");
JRadioButton truckRadio = new JRadioButton("Pickup Truck");
JRadioButton suvRadio = new JRadioButton("SUV");
JCheckBox leather = new JCheckBox("Leather Seats");
JCheckBox ac = new JCheckBox("Air Conditioning");
JCheckBox sat = new JCheckBox("Sattelite Radio");
JCheckBox warmer = new JCheckBox("Seat Warmers");
String optionsSelected;
String carSelected;
ActionListener listen = new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae){
JOptionPane.showMessageDialog(
CarSelector.this, sb.toString + ssb.toString());
}
};
CarSelector(){
super("Vehicle Selector");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(300, 300);
CarGUI();
}
public void CarGUI(){
JPanel vehicleTypes = new JPanel();
JPanel carOptions = new JPanel();
JPanel submitButton = new JPanel();
carRadio.addActionListener(listen);
vanRadio.addActionListener(listen);
truckRadio.addActionListener(listen);
suvRadio.addActionListener(listen);
leather.addActionListener(listen);
ac.addActionListener(listen);
sat.addActionListener(listen);
warmer.addActionListener(listen);
submit.addActionListener(listen);
add(submitButton);
submitButton.setLayout(new BoxLayout(submitButton, BoxLayout.X_AXIS));
submitButton.setBounds(100, 150, 100, 100);
add(vehicleTypes);
vehicleTypes.setLayout(new BoxLayout(vehicleTypes, BoxLayout.Y_AXIS));
vehicleTypes.setBounds(150,0,125,125);
add(carOptions);
carOptions.setLayout(new BoxLayout(carOptions, BoxLayout.Y_AXIS));
vehicleTypes.add(carLabel);
vehicleTypes.add(carRadio);
vehicleTypes.add(vanRadio);
vehicleTypes.add(truckRadio);
vehicleTypes.add(suvRadio);
group.add(carRadio);
group.add(vanRadio);
group.add(truckRadio);
group.add(suvRadio);
carOptions.add(options);
carOptions.add(leather);
carOptions.add(ac);
carOptions.add(sat);
carOptions.add(warmer);
submitButton.add(submit);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void itemStateChanged(ItemEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
This is the code for running the program.
public class GUITest {
public static void main (String[] args){
CarSelector car = new CarSelector();
}
}
To further my comment above, for your use case, you should only be adding an ActionListener to your submit button.
Within the ActionListener you will need to call isSelected on each of your JRadioButtons and JCheckBoxes.
Something like this will do the trick:
public void CarGUI(){
JPanel vehicleTypes = new JPanel();
JPanel carOptions = new JPanel();
JPanel submitButton = new JPanel();
//The below syntax assumes you are running Java 8. Please let me know if you are not
//and I will update the syntax
submit.addActionListener((e)=>{
StringBuilder sb = new StringBuilder();
sb.append("Vehicle Type: ");
if(carRadio.isSelected()) sb.append("Car");
else if(vanRadio.isSelected()) sb.append("Van");
//Continue with the rest of radiobuttons
// and do the same with the Checkboxes just make sure to
// not use "else" if and make a new conditional for each Checkbox
JOptionPane.showMessageDialog(
CarSelector.this, sb.toString);
});
A cleaner and more sustainable way to handle this sort of thing would be to put your JRadioButtons and JCheckBoxes in Arrays. It would make your ActionListener code a lot cleaner and it would be easier to add more options because your would just need to insert a new checkbox or radiobutton into your arrays and not have to change any of your ActionListener code.
JRadioButton[] vehicleTypes = new JRadioButton[] { new JRadioButton("Car", true), new JRadioButton("Van") ... };
// then in ActionListener
for(JRadioButton rBtn: vehicleTypes){
if(rBtn.isSelected()){
sb.append(rBtn.getText());
}
}
I´m creating a program in NetBeans where the user can create their own CSV-file. I've made a GUI. When I press the button, I want a new JLabel and a new JTextField to appear underneath the existing ones, for as many times as the button is pressed. How do I do that?
I've done something similiar and I'm using a JPanel with GroupLayout to solve this problem and that's my code:
EDIT - Your question aroused my interest and I've changed my code to your needs (of course only the basic, you will have to improve it)
Global variables
private GroupLayout m_layout;
private SequentialGroup m_verticalSg;
private ArrayList<Component> m_labelList;
private ArrayList<Component> m_textFieldList;
private ParallelGroup m_horizontalPgLabels;
private ParallelGroup m_horizontalPgTextfields;
Method createLayout()
Creates the layout for your panel which should contain the label & textfield components
private void createLayout()
{
m_layout = new GroupLayout(YOUR_PANEL);
YOUR_PANEL.setLayout(m_layout);
//This SequentialGroup is used for the VerticalGroup
m_verticalSg = m_layout.createSequentialGroup();
m_verticalSg.addContainerGap();
//Two ParallelGroups are used. One for all labels and the other one for all textfields
m_horizontalPgLabels = m_layout.createParallelGroup(GroupLayout.Alignment.LEADING);
m_horizontalPgTextfields = m_layout.createParallelGroup(GroupLayout.Alignment.LEADING);
//These component lists are used for linkSize() -> Equalize components width
m_labelList = new ArrayList<>();
m_textFieldList = new ArrayList<>();
m_layout.setHorizontalGroup(m_layout.createParallelGroup()
.addGroup(m_layout.createSequentialGroup()
.addContainerGap()
.addGroup(m_horizontalPgLabels)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) //Create gap between horizontal groups
.addGroup(m_horizontalPgTextfields)
.addContainerGap()));
m_layout.setVerticalGroup(m_layout.createParallelGroup().addGroup(m_verticalSg.addContainerGap()));
}
Method addNewRow()
Call this method from your button click event
private void addNewRow()
{
if(m_layout == null)
createLayout();
Dimension dimLabel = new Dimension(100, 15);
Dimension dimTextfield = new Dimension(200, 20);
//Create a new label
JLabel lbl = new JLabel();
lbl.setText("Your text");
lbl.setIcon(null/*Your icon*/);
lbl.setSize(dimLabel);
lbl.setPreferredSize(dimLabel);
//Create a new textfield
JTextField txtField = new JTextField();
txtField.setSize(dimTextfield);
txtField.setPreferredSize(dimTextfield);
//Add components to arrays and increase index
m_labelList.add(lbl);
m_textFieldList.add(txtField);
//Create new ParallelGroup for the vertical SequentialGroup
ParallelGroup newVerticalParallelGroup = m_layout.createParallelGroup(GroupLayout.Alignment.LEADING);
newVerticalParallelGroup.addComponent(lbl);
newVerticalParallelGroup.addComponent(txtField);
m_verticalSg.addGroup(newVerticalParallelGroup);
m_verticalSg.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
//Add the new label to the horizontal label group
m_horizontalPgLabels.addComponent(lbl, GroupLayout.Alignment.CENTER);
//Add the new textfield to the horizontal textfield group
m_horizontalPgTextfields.addComponent(txtField);
m_layout.linkSize(SwingConstants.HORIZONTAL, m_labelList.toArray(new Component[m_labelList.size()]));
m_layout.linkSize(SwingConstants.HORIZONTAL, m_textFieldList.toArray(new Component[m_textFieldList.size()]));
}
The last step is to add an ActionListener to your button to call the method addNewRow().
jButton1.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
addNewRow();
}
});
Feel free to ask me if something is unclear.
Hi I am trying to create Scroll Bar for my JFrame. I created JPanel object and set components into JPanel. Then created a JScrollPane object for the panel. Then add the ScrollPane object to JFrame. I am not seeing any scrollbar. Also I am wondering if there is a option in JPanel that would resize the object inside Jpanel automatically according to the zoom level of the JPanel. Any help would be highly appreciated.
public class xmlottgui {
private JPanel Container;
private JFrame frmCreateXml;
private JTextField titlename;
private JLabel lbltitlename;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
xmlottgui window = new xmlottgui();
window.frmCreateXml.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public xmlottgui() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
Container = new JPanel();
Container.setLayout(null);
//JScrollPane pane=new JScrollPane(Container,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
frmCreateXml = new JFrame();
frmCreateXml.setTitle("Create XML");
frmCreateXml.setBounds(100, 100, 1000, 1200);
frmCreateXml.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmCreateXml.getContentPane().setLayout(null);
//Create MenuBar
JMenuBar menuBar = new JMenuBar();
Container.add(menuBar);
JMenu mnFile = new JMenu("File");
menuBar.add(mnFile);
JMenuItem mntmImportFromCsv = new JMenuItem("Import From Excel File");
//Add menu item Exit
JMenuItem mntmexit = new JMenuItem("Exit");
mntmexit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
mnFile.add(mntmexit);
showform();
JScrollPane pane=new JScrollPane(Container,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
pane.setLayout(null);
frmCreateXml.setContentPane(pane);
frmCreateXml.getContentPane().add(pane);
}
private void showform(){
titlename = new JTextField();
titlename.setBounds(164, 27, 749, 26);
Container.add(titlename);
titlename.setColumns(10);
lbltitlename = new JLabel("Title Name");
lbltitlename.setBackground(Color.GRAY);
lbltitlename.setBounds(22, 1000, 90, 16);
Container.add(lbltitlename);
}
This:
pane.setLayout(null);
Will completely disable your JScrollPane and prevent it from working as it will prevent the JScrollPane from displaying and manipulating its view port properly. JScrollPanes have there own very special layout manager, one you never want to muck with unless you are very clever and know what you're doing. As a general rule you should almost never use null layouts.
Also this is not correct:
frmCreateXml.setContentPane(pane);
frmCreateXml.getContentPane().add(pane);
You make pane the contentPane and then add pane to itself.
AND THIS is messing you up:
frmCreateXml.getContentPane().setLayout(null);
You will want to learn about and use the layout managers as it will make your life much easier.
I'm working on an assignment for class where we need to create a JComboBox and each option opens a new window where you can do whatever you want on those new windows. Please keep in mind I'm very new to GUI and new to Java in general, in case my questions are dumb.
I have a question and an issue...
My question:
When the user selects "The Matrix" option a new window pops up with a quote and two buttons. Right now I have two JPanels (panel and panel2) panel adds the quote to the NORTH position and then panel2 adds the two buttons to the CENTER position both using BorderLayout. My question is am I doing this correctly...Could I use just panel to add the quote and the buttons or is it necessary to create separate panels for separate items being added to the JFrame? When I had them both added to the same panel the quote was not on the window when I ran the program.
panel.add(matrixQuote);
newFrame.add(panel, BorderLayout.NORTH);
That's how I had it when it wasn't showing up ^^^
I GOT THE ISSUE WITH CLEARING THE JFRAME FIXED
I am trying to add an ActionListener to the bluePill button and instead of opening another new window I thought I could clear everything from the existing window when the button is pressed and then display something new on said window. The only info I could find on this is how I have it in the actionPerformed method below. I'll post a snippet of what I'm talking about directly below and then all my code below that just in case.
All my code...
public class MultiForm extends JFrame{
private JComboBox menu;
private JButton bluePill;
private JButton redPill;
private JLabel matrixQuote;
private int matrixSelection;
private JFrame newFrame;
private JPanel panel;
private JPanel panel2;
private static String[] fileName = {"", "The Matrix", "Another Option"};
public MultiForm() {
super("Multi Form Program");
setLayout(new FlowLayout());
menu = new JComboBox(fileName);
add(menu);
TheHandler handler = new TheHandler();
menu.addItemListener(handler);
}
public void matrixPanel() {
TheHandler handler = new TheHandler();
//Create a new window when "The Matrix" is clicked in the JCB
newFrame = new JFrame();
panel = new JPanel();
panel2 = new JPanel();
newFrame.setLayout(new FlowLayout());
newFrame.setSize(500, 300);
newFrame.setDefaultCloseOperation(newFrame.EXIT_ON_CLOSE);
matrixQuote = new JLabel("<html>After this, there is no turning back. "
+ "<br>You take the blue pill—the story ends, you wake up "
+ "<br>in your bed and believe whatever you want to believe."
+ "<br>You take the red pill—you stay in Wonderland, and I show"
+ "<br>you how deep the rabbit hole goes. Remember: all I'm "
+ "<br>offering is the truth. Nothing more.</html>");
panel2.add(matrixQuote);
newFrame.add(panel2, BorderLayout.NORTH);
//Blue pill button and picture.
Icon bp = new ImageIcon(getClass().getResource("Blue Pill.png"));
bluePill = new JButton("Blue Pill", bp);
panel2.add(bluePill);
bluePill.addActionListener(handler);
//Red pill button and picture
Icon rp = new ImageIcon(getClass().getResource("Red Pill.png"));
redPill = new JButton("Red Pill", rp);
panel2.add(redPill);
newFrame.add(panel2, BorderLayout.CENTER);
newFrame.setVisible(true);
}
private class TheHandler implements ItemListener, ActionListener{
public void itemStateChanged(ItemEvent IE) {
//listen for an item to be selected.
if(IE.getStateChange() == ItemEvent.SELECTED) {
Object selection = menu.getSelectedItem();
if("The Matrix".equals(selection)) {
matrixPanel();
}
else if("Another Option".equals(selection)) {
}
}
}
public void actionPerformed(ActionEvent AE) {
if(AE.getSource() == bluePill) {
newFrame.remove(panel);
newFrame.remove(panel2);
newFrame.repaint();
}
}
}
//MAIN
public static void main(String[] args) {
MultiForm go = new MultiForm();
go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go.setSize(400, 200);
go.setVisible(true);
}
}
Use a Card Layout. You can swap panels as required.
The tutorial has a working example.
You can use:
jpanel.removeAll();
Either to delete a certain JComponent by using the JComponent itself like:
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
frame.remove(panel);
panel.getGraphics().clearRect(0, 0, panel.getWidth(), panel.getHeight());
I need to create a combo box with multi-selection, how to achieve that?
I know, that the question is rather old, but for those, who still looks for solution of this problem, try the following code:
public class ComboSelections {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, UnsupportedLookAndFeelException {
UIManager.setLookAndFeel((LookAndFeel) Class.forName("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel").newInstance());
final JPopupMenu menu = new JPopupMenu();
JMenuItem one = new JCheckBoxMenuItem("One");
JMenuItem two = new JCheckBoxMenuItem("Two");
JMenuItem three = new JCheckBoxMenuItem("Three");
JMenuItem four = new JCheckBoxMenuItem("Four");
menu.add(one);
menu.add(two);
menu.add(three);
menu.add(four);
final JButton button = new JButton("Click me");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (!menu.isVisible()) {
Point p = button.getLocationOnScreen();
menu.setInvoker(button);
menu.setLocation((int) p.getX(),
(int) p.getY() + button.getHeight());
menu.setVisible(true);
} else {
menu.setVisible(false);
}
}
});
one.addActionListener(new OpenAction(menu, button));
two.addActionListener(new OpenAction(menu, button));
three.addActionListener(new OpenAction(menu, button));
four.addActionListener(new OpenAction(menu, button));
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.add(button);
frame.getContentPane().add(panel);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static class OpenAction implements ActionListener {
private JPopupMenu menu;
private JButton button;
private OpenAction(JPopupMenu menu, JButton button) {
this.menu = menu;
this.button = button;
}
#Override
public void actionPerformed(ActionEvent e) {
menu.show(button, 0, button.getHeight());
}
}
}
There are a few basic problems with creating custom combobox popup content (like a list with multiselection):
1. Default UI suggests JList usage as the content so to change that behavior you will have to change the whole ComboBoxUI
2. You cannot simply change the default combobox list into multiselection one due to the fact that only one value gets "selected" at the end and list has default rollover selection mouse listener, that will make you unable to choose more than one element
So i'd reccomend you to use simple JList instead of combobox or look into using some extended components libraries like JideSoft - they have this component and lots more which you won't be able to quickly create using Swing features.