This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
how can I get the buttons to appear on the line underneath the textarea?
//Imports
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
public class ProfessorPhysInstall {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
//Variables
final JFrame mainframe = new JFrame();
mainframe.setSize(500, 435);
final JPanel cards = new JPanel(new CardLayout());
final CardLayout cl = (CardLayout)(cards.getLayout());
mainframe.setTitle("Future Retro Gaming Launcher");
//Screen1
JPanel screen1 = new JPanel();
JTextPane TextPaneScreen1 = new JTextPane();
TextPaneScreen1.setEditable(false);
TextPaneScreen1.setBackground(new java.awt.Color(240, 240, 240));
TextPaneScreen1.setText("Welcome to the install wizard for Professor Phys!\n\nPlease agree to the following terms and click the next button to continue.");
TextPaneScreen1.setSize(358, 48);
TextPaneScreen1.setLocation(0, 0);
TextPaneScreen1.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.black),BorderFactory.createEmptyBorder(5, 5, 5, 5)));
TextPaneScreen1.setMargin(new Insets(4,4,4,4));
screen1.add(TextPaneScreen1);
JTextArea TextAreaScreen1 = new JTextArea();
JScrollPane sbrText = new JScrollPane(TextAreaScreen1);
TextAreaScreen1.setRows(15);
TextAreaScreen1.setColumns(40);
TextAreaScreen1.setEditable(false);
TextAreaScreen1.setText("Lots of text");
TextAreaScreen1.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.black),BorderFactory.createEmptyBorder(5, 5, 5, 5)));
TextAreaScreen1.setMargin(new Insets(4,4,4,4));
screen1.add(sbrText);
final JCheckBox Acceptance = new JCheckBox();
Acceptance.setText("I Accept The EULA Agreenment.");
screen1.add(Acceptance);
final JButton NextScreen1 = new JButton();
NextScreen1.setText("Next");
NextScreen1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if(Acceptance.isSelected())
cl.next(cards);
}
});
screen1.add(NextScreen1);
JButton CancelScreen1 = new JButton();
CancelScreen1.setText("Cancel");
CancelScreen1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
});
screen1.add(CancelScreen1);
cards.add(screen1);
//Screen2
JPanel screen2 = new JPanel();
JTextPane TextPaneScreen2 = new JTextPane();
TextPaneScreen2.setEditable(false);
TextPaneScreen2.setBackground(new java.awt.Color(240, 240, 240));
TextPaneScreen2.setText("Please select the Future Retro Gaming Launcher.");
TextPaneScreen2.setSize(358, 48);
TextPaneScreen2.setLocation(0, 0);
TextPaneScreen2.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.black),BorderFactory.createEmptyBorder(5, 5, 5, 5)));
TextPaneScreen2.setMargin(new Insets(4,4,4,4));
screen2.add(TextPaneScreen2);
final JButton BackScreen2 = new JButton();
BackScreen2.setText("Back");
BackScreen2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if(Acceptance.isSelected())
cl.previous(cards);
}
});
screen2.add(BackScreen2);
final JButton NextScreen2 = new JButton();
NextScreen2.setText("Next");
NextScreen2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if(Acceptance.isSelected())
cl.next(cards);
}
});
screen2.add(NextScreen2);
JButton CancelScreen2 = new JButton();
CancelScreen2.setText("Cancel");
CancelScreen2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
});
screen2.add(CancelScreen2);
cards.add(screen2);
mainframe.add(cards);
mainframe.setVisible(true);
}
}
This is what it looks like
The default layout manager for JPanel is FlowLayout. As the name suggests, it simply flows the components one after the other.
You will need to try a different layout manager, something like GridBagLayout will do what you want, but it is a complex layout. You may be better of trying to use compound layouts to achieve the same effect.
That is, break the UI down into small chunks and apply different layout managers for each group.
Check out...
A Visual Guide to Layout Managers
Using Layout Managers
You will also benifit from reading...
Initial Threads
Code Conventions for the Java Programming Language
Ps...
You may also want to consider breaking each screen up into it's own class, the code as it stands is very hard to read and understands - IMHO
Use an appropriate LayoutManager
You've added all the components to screen2 which has a FlowLayout by default. There are many different ways to achieve what you're after.
More reading: Using Layout Managers
The usual way is to combine layouts for the look needed. E.G.
import java.awt.*;
import javax.swing.*;
public class ProfessorPhysInstall {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
//Variables
final JFrame mainframe = new JFrame();
mainframe.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
mainframe.setSize(500, 435);
final JPanel cards = new JPanel(new BorderLayout());
mainframe.setTitle("Future Retro Gaming Launcher");
//Screen2
JPanel screen2 = new JPanel();
JTextPane TextPaneScreen2 = new JTextPane();
TextPaneScreen2.setText("Please select the Future Retro Gaming Launcher.");
// set the preferred size, rather than the size!
//TextPaneScreen2.setSize(358, 48);
TextPaneScreen2.setPreferredSize(new Dimension(358, 48));
TextPaneScreen2.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.black),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
TextPaneScreen2.setMargin(new Insets(4,4,4,4));
screen2.add(TextPaneScreen2);
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.CENTER, 5,5));
final JButton BackScreen2 = new JButton();
BackScreen2.setText("Back");
buttons.add(BackScreen2);
final JButton NextScreen2 = new JButton("Next");
buttons.add(NextScreen2);
JButton CancelScreen2 = new JButton("Cancel");
buttons.add(CancelScreen2);
cards.add(screen2, BorderLayout.PAGE_START);
cards.add(buttons, BorderLayout.PAGE_END);
mainframe.add(cards);
mainframe.pack();
mainframe.setVisible(true);
}
}
Tips
Please learn common Java naming conventions (specifically the case used for the names) for class, method & attribute names & use them consistently.
For better help sooner, post an SSCCE.
Don't set the size of top level containers. Instead layout the content & call pack().
See the Nested Layout Example for ideas about how to combine layouts to create the required layout.
Also heed the advice already offered on the other two answers.
Related
I built a great GUI using the frowned upon null layout (I defined a lot of constants and used a window resize listener to make it easy). Everything worked perfectly until I started using a new computer. Now, the component's are not positioned properly (from the picture you can see that the components are offset down and right). After researching the problem I learned that layout managers make sure that the components are positioned properly throughout different machines. Because of this, I would like to start rebuilding the GUI in an actual layout manager. The problem is that I often feel limited in the way I position components when attempting to use an actual layout manager.
For anyone who is curious, I was originally using a dell inspiron laptop with windows 10, and have moved to an Asus Laptop (I don't know the actual model, but the touch screen can detach from the keyboard), also with windows 10.
My question:
Which layout manager would be the fastest and easiest to build the GUI shown in the picture above (out of the stock Swing Layouts and others). I would like this layout to respect the components' actual sizes for only a few but not all of the components. Using this layout, how would I go about positioning the inventory button (the hammer at the bottom left) so that the bottom left corner of the inventory button is 5 pixels up and right from the bottom left corner of the container, even after resizing the container?
Thanks in advance. All help is appreciated.
EDIT: The "go find a key" and "Attempt to force the door open" options should have their sizes respected.
The simplest solution that comes to my mind is a BorderLayout for the main panel. Add the textarea to NORTH / PAGE_START. Make another BorderLayout containing the inventory button (WEST / LINE_START) and the location label (EAST / LINE_END). Add that to SOUTH / PAGE_END of the main BorderLayout. Then just add a BoxLayout with vertical alignment to the main BorderLayout's CENTER containing the two buttons. Here's a tutorial for the standard layout managers.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Example {
public Example() {
JTextArea textArea = new JTextArea("There is a locked door");
textArea.setRows(5);
textArea.setBorder(BorderFactory.createLineBorder(Color.GRAY));
textArea.setEditable(false);
WhiteButton button1 = new WhiteButton("Go find a key") {
#Override
public Dimension getMinimumSize() {
return new Dimension(200, 25);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 25);
}
#Override
public Dimension getMaximumSize() {
return new Dimension(200, 25);
}
};
WhiteButton button2 = new WhiteButton("Attempt to force the door open");
button2.setMargin(new Insets(0, 60, 0, 60));
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
buttonPanel.add(button1);
buttonPanel.add(Box.createVerticalStrut(5));
buttonPanel.add(button2);
WhiteButton inventoryButton = new WhiteButton(
new ImageIcon(new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB)));
JLabel locationLabel = new JLabel("Location: 0");
locationLabel.setVerticalAlignment(JLabel.BOTTOM);
JPanel southPanel = new JPanel(new BorderLayout());
southPanel.add(inventoryButton, BorderLayout.WEST);
southPanel.add(locationLabel, BorderLayout.EAST);
JPanel mainPanel = new JPanel(new BorderLayout(0, 5));
mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
mainPanel.add(textArea, BorderLayout.NORTH);
mainPanel.add(buttonPanel);
mainPanel.add(southPanel, BorderLayout.SOUTH);
JFrame frame = new JFrame("Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
private class WhiteButton extends JButton {
public WhiteButton() {
setBackground(Color.WHITE);
}
public WhiteButton(String text) {
this();
setText(text);
}
public WhiteButton(ImageIcon icon) {
this();
setIcon(icon);
setBorder(BorderFactory.createLineBorder(Color.GRAY));
}
}
}
I want to write a simple Swing application with a button and a text field at the bottom. I'm using a JTextField but it is not clickable. I searched on the web and SO, but I could not find a solution. In question How to Set Focus on JTextField?, I found the following :
addWindowListener( new WindowAdapter() {
public void windowOpened( WindowEvent e ){
entry.requestFocus();
}
});
but this does not help. In this other question (How do you set a focus on Textfield in Swing?) I found Component.requestFocus() but this does not work either. I also tried
entry.setFocusable(true);
entry.setEditable(true);
entry.setEnabled(true);
without effects. My code:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class StackSample extends JFrame {
public StackSample() {
initUI();
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void initUI() {
JPanel panel = new JPanel(new BorderLayout());
add(panel, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel(new FlowLayout());
panel.add(bottomPanel, BorderLayout.SOUTH);
JButton buttonDraw = new JButton("Draw");
bottomPanel.add(buttonDraw);
JTextField entry = new JTextField();
bottomPanel.add(entry);
setPreferredSize(new Dimension(250, 150));
setLocationRelativeTo(null);
}
private static final long serialVersionUID = 8359448221778584189L;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MyApp app = new MyApp();
app.setVisible(true);
}
});
}
}
Your JTextField is clickable. The only problem is that it's too small.
This is because you're using FlowLayout, which will make components as small as possible.
One solution is to simply switch to a layout that allows components to fill as much space as possible, such as BoxLayout:
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel,BoxLayout.X_AXIS));
You haven't specified a size for your JTextField, so it defaults to zero characters wide. Try using the constructor that specifies the number of columns.
Also, what is MyApp? I can't see any evidence that your StackSample is ever created or used.
I am currently working on a short Java Swing project using Eclipse (Luna, Win 8.1). The aim is to display a frame that contains a menu. The menu has different pages (Main, Options, etc.), realized by JPanels with Buttons, Labels, etc. Those JPanels are organized by a CardLayout, in such a manner that calling the CardLayout.show(..)-method switches between different menu pages. When I stopped programming two days ago, everything was working perfectly. However, when I wanted to continue yesterday morning, my code seemed to completely ignore the CardLayout: Buttons situated in other cards would pop up through the first card's background when moving the mouse cursor over their positions. I tried to fix that (researching, using backups, etc.) for 17 hours straight. The problem still persists and I am pretty desperate by now =/. The following SSCCE shows the same behaviour (move mouse over bottom left corner to see the "Option" card's "Back" button pop up).
package sscce;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainFrame extends JFrame {
private CardLayout mainWindowLayout;
// mainPanel will be used as the MainFrame's main unit to manage Components
private JPanel mainPanel;
// Constructor
public MainFrame() {
setTitle("sscce");
setPreferredSize(new Dimension(800, 600));
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
mainPanel = new JPanel();
mainPanel.setPreferredSize(getSize());
mainWindowLayout = new CardLayout();
mainPanel.setLayout(mainWindowLayout);
buildMainMenu();
buildOptions();
getContentPane().add(mainPanel);
mainPanel.setVisible(true);
// starting application it will "show" (container,
// contentIdentifier(String))
mainWindowLayout.show(mainPanel, "2");
pack();
setVisible(true);
}// Constructor
private void buildMainMenu() {
JPanel panelMainMenu = new JPanel(new GridBagLayout());
panelMainMenu.setBackground(Color.orange);
// 1 Button (centered) to go to Options-Card
JButton bnOptions = new JButton("Options");
// Button Functionality
bnOptions.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
mainWindowLayout.show(mainPanel, "2");
}
});
panelMainMenu.add(bnOptions);
panelMainMenu.setOpaque(true);
// container content identifier(String)
mainPanel.add(panelMainMenu, "1");
panelMainMenu.setVisible(true);
}// buildMainMenu
private void buildOptions() {
JPanel panelOptions = new JPanel();
panelOptions.setLayout(new GridBagLayout());
// standardized margins for all Elements:
final Insets gbcInsets = new Insets(5, 5, 5, 5);
panelOptions.setBackground(Color.white);
JPanel fillerRight = new JPanel();
JPanel fillerTop = new JPanel();
JButton bnOptBack = new JButton("Back");
bnOptBack.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
mainWindowLayout.show(mainPanel, "1");
}
});
// add filler panels to keep button in position
fillerRight.setBackground(Color.red);
fillerRight.setOpaque(true);
panelOptions.add(fillerRight, new GridBagConstraints(1, 1, 1, 2, 1, 0,
GridBagConstraints.NORTH, GridBagConstraints.BOTH, gbcInsets,
0, 0));
fillerRight.setVisible(true);
fillerTop.setBackground(Color.pink);
fillerTop.setOpaque(true);
panelOptions.add(fillerTop, new GridBagConstraints(0, 0, 2, 1, 0, 1,
GridBagConstraints.NORTH, GridBagConstraints.BOTH, gbcInsets,
0, 0));
fillerTop.setVisible(true);
// 1 Button in lower left hand corner, sends you back to MainMenu-card
panelOptions.add(bnOptBack, new GridBagConstraints(0, 1, 1, 1, 0, 0,
GridBagConstraints.NORTH, GridBagConstraints.BOTH, gbcInsets,
0, 0));
bnOptBack.setVisible(true);
panelOptions.setOpaque(true);
// container content identifier(String)
mainPanel.add(panelOptions, "2");
panelOptions.setVisible(true);
}// buildOptions
public static void main(String[] args) {
MainFrame m = new MainFrame();
}// main
}// MainFrame
Any help is greatly appreciated.
Thanks in advance :)
Edit: I guess you don't need to look at the "buildMainMenu" and "buildOptions" methods too closely, the setup for the single menu pages seems to work fine.
It works as expected on my machine when I comment out the following two lines
panelOptions.setVisible(true);
and
panelMainMenu.setVisible(true);
When using the CardLayout, you just add the components and use CardLayout#show to decide which one you show. Calling setVisible first seems to cause problems (for whatever reason).
Making sure that the Swing code is triggered on the EDT is also a good idea:
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MainFrame m = new MainFrame();
}
});
I am creating a basic user interface in Swing and was hoping for some help. Below is a screenshot of what I am trying to achieve:
My code currently is as follows:
package testui;
import java.awt.Container;
import javax.swing.*;
public class TestUI{
private JTextField outputArea = new JTextField();
private JTextField errorReportArea = new JTextField();
private JPanel inputPanel = new JPanel();
private JLabel nameLabel = new JLabel("Item Name");
private JLabel numberLabel = new JLabel("Number of units (or Volume in L)");
private JLabel priceLabel = new JLabel("Price per unit (Or L) in pence");
private JTextField nameField = new JTextField(10);
private JTextField numberField = new JTextField(10);
private JTextField priceField = new JTextField(10);
private JButton addVolumeButton = new JButton("Add by Volume");
private JButton addNumberButton = new JButton("Add by number of units");
public TestUI() {
JFrame frame = new JFrame("Fuel Station");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
outputArea.setEditable(false);
errorReportArea.setEditable(false);
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.X_AXIS));
inputPanel.add(nameLabel);
inputPanel.add(nameField);
inputPanel.add(numberLabel);
inputPanel.add(numberField);
inputPanel.add(priceLabel);
inputPanel.add(priceField);
inputPanel.add(addVolumeButton);
inputPanel.add(addNumberButton);
Container contentPane = frame.getContentPane();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
contentPane.add(outputArea);
contentPane.add(errorReportArea);
contentPane.add(inputPanel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
TestUI test1 = new TestUI();
}
}
Which looks like this:
So what I would like to do is set a specific size for the top two JTextFields, as the top one will contain multiple lines of text, and the one below will contain just one line of text. I am unsure how to do this without using setSize, as I have been told it is bad coding practice to use this.
I would also like to add some padding between the JLabels, JTextFields and JButtons in the bottom JPanel.
If anyone could give me some suggestions on resizing these components I would be most grateful
Since you want your textfields to be multilined, use JTextAreas. JTextFields are single lined only.
Your components are right next to each other which isn't the same look as your intended outcome. There may be some method that gives your components some breathing room before you would call frame.pack()
Look for any method that can make a component fill the total amount of room it's given; especially when you want something to fill a large chunk of space.
You can set the number of columns instead of using setSize() for your JTextFields/JTextAreas. Just saying.
Reviewing all of Java's Layout Managers would help you get a grasp of the capabilities and use cases for each layout manager
There are a few layout managers that are flexible enough to perform this, such as Mig, Gridbag, and SpringLayout.
In your case, you'd have the following constraints:
outputarea - south border constrained to be ###px from the north border of the contentPane
errorReportArea - north border constrained to be 0px from outputarea's south, and south border constrained to be 0px from inputPanel's north.
inputPanel - north border constrained to be ##px from the south border of the contentPane.
GUI builders such as WindowBuilder will allow you to do this pretty quickly. You just drop in the layout onto the contentPane and then set the constraints.
If you have to use a box layout look at the glue and rigidArea methods in Box. If you can use other layouts, go with those suggested by the other answers.
I have created a solution with the MigLayout manager.
Here are some recommendations:
Put application code outside the constructor; in the solution, the code
is placed in the initUI() method.
The application should be started on EDT by calling the
EventQueue.invokeLater(). (See the main() method of the provided solution.)
Use a modern, flexible layout manager: MigLayout, GroupLayout, or FormLayout.
Take some time to study them to fully understand the layout management process. It
is important have a good understanding of this topic.
Shorten the labels; use more descriptive tooltips
instead.
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
public class MigLayoutSolution extends JFrame {
private JTextArea outputArea;
private JTextField errorReportField;
private JLabel nameLabel;
private JLabel numberLabel;
private JLabel priceLabel;
private JTextField nameField;
private JTextField numberField;
private JTextField priceField;
private JButton addVolumeButton;
private JButton addNumberButton;
public MigLayoutSolution() {
initUI();
}
private void initUI() {
setLayout(new MigLayout());
outputArea = new JTextArea(10, 20);
errorReportField = new JTextField(15);
nameLabel = new JLabel("Item name");
numberLabel = new JLabel("# of units");
numberLabel.setToolTipText("Number of units (or Volume in L)");
priceLabel = new JLabel("Price per unit");
priceLabel.setToolTipText("Price per unit (Or L) in pence");
nameField = new JTextField(10);
numberField = new JTextField(10);
priceField = new JTextField(10);
addVolumeButton = new JButton("AddVol");
addVolumeButton.setToolTipText("Add by Volume");
addNumberButton = new JButton("AddNum");
addNumberButton.setToolTipText("Add by number of units");
add(new JScrollPane(outputArea), "grow, push, wrap");
add(errorReportField, "growx, wrap");
add(nameLabel, "split");
add(nameField);
add(numberLabel);
add(numberField);
add(priceLabel);
add(priceField);
add(addVolumeButton);
add(addNumberButton);
pack();
setTitle("Fuel station");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutSolution ex = new MigLayoutSolution();
ex.setVisible(true);
}
});
}
}
Hi this is a bit of a basic question. In my code I create a gui in a constructor then nest a ActionListener class to handle button changes. This code will create the gui and the action listener runs through the actionPerformed method correctly. However, I've tried multiple ways to change the panel in the gui but I feel like the way I have the program set up it is not possible for this to work. Sorry if this is a repeat but after searching for a while on S.O. I haven't found a good example that would help me with my problem.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import org.math.plot.Plot2DPanel;
import org.math.plot.plotObjects.BaseLabel;
public class GraphGui extends JFrame {
//default width and height of the GUI
private static final int WIDTH = 1200;
private static final int HEIGHT = 700;
GraphPlot gp = new GraphPlot();
Plot2DPanel plotPanel =gp.determinePlotToPlot("duration");
/**
* This is the constructor that initializes the JFrame and the layout of the GUI.
* The radio buttons are also created here and grouped accordingly.
*/
public GraphGui() {
//title of GUI
setTitle("VibeTech Graph Gui");
//First JRadioButton for date vs duration
JRadioButton durToDate = new JRadioButton("Duration vs. Date");
durToDate.addActionListener(new RadioButtonListener());
durToDate.setActionCommand("duration");
durToDate.setSelected(true);
//JRadioButton for weight vs date
JRadioButton weightToDate = new JRadioButton("Weight vs. Date");
weightToDate.addActionListener(new RadioButtonListener());
weightToDate.setActionCommand("weight");
//JRadioButton for plan type vs date
JRadioButton planToDate = new JRadioButton("Plan vs. Date");
planToDate.addActionListener(new RadioButtonListener());
planToDate.setActionCommand("level");
//button group of the buttons to display them as one group
ButtonGroup group = new ButtonGroup();
group.add(planToDate);
group.add(weightToDate);
group.add(durToDate);
//create JPanel to add objects to
JPanel jplRadio = new JPanel();
jplRadio.setLayout(new GridLayout(0, 1));
//add radio buttons
jplRadio.add(planToDate);
jplRadio.add(weightToDate);
jplRadio.add(durToDate);
Plot2DPanel dvt = new Plot2DPanel();
dvt.addLinePlot("Duration over Time", gp.getDate(), gp.getDuration());
BaseLabel title = new BaseLabel("Duration over Time", Color.RED,
0.5, 1.1);
title.setFont(new Font("Courier", Font.BOLD, 20));
dvt.addPlotable(title);
dvt.setAxisLabels("Time", "Duration");
setLayout(new BorderLayout());
add(jplRadio, BorderLayout.WEST);
add(plotPanel, BorderLayout.EAST);
setSize(WIDTH, HEIGHT);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
//main method to run program
public static void main(String [ ] args)
{
//create new GUI
#SuppressWarnings("unused")
GraphGui test = new GraphGui();
}
//create a radio button listener to switch graphs on button press
class RadioButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("duration")) {
plotPanel = gp.determinePlotToPlot("duration");
} else if (e.getActionCommand().equals("weight")) {
plotPanel = gp.determinePlotToPlot("weight");
} else if (e.getActionCommand().equals("level")) {
plotPanel = gp.determinePlotToPlot("level");
}
//here is where I tried to do removes, adds, and validates but
//I have trouble getting to the frame itself to remove the JPanel
//component. I think this is a setup problem.
}
}
}
You would need to add the panel and revalidate/repaint the JFrame for it to appear:
add(plotPanel, BorderLayout.EAST);
revalidate();
repaint();
Better to use CardLayout to manage this type of functionality.
Try using CardLayout for switching between panels. Here is my solution for a similar question: https://stackoverflow.com/a/9377623/544983