I want to create a program with a GUI where I have a Choice with three different options.
I have to realize it with CardLayout but my problem is that I don't know how to switch the CardLayoutPanel to the one I selected in the Choice.
Choice ch = new Choice();
Panel cl = new Panel(new CardLayout());
Panel one = new Panel();
Panel two = new Panel();
Panel three = new Panel();
and in the constructor I have:
// CARD LAYOUT PANELS
cl.add(one, "1");
cl.add(two, "2");
cl.add(three, "3");
f.setLayout(new FlowLayout());
// CHOICE-OPTIONS
ch.add("one");
ch.add("two");
ch.add("three");
How can I add an ActionListener to switch between the different Panels using the Choice ?
(Please don't comment google it - I already did, otherwise I wouldn't ask)
Thank you!
Here is a SSCCE (Short Self Contained Correct Example). Notes after the code.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Choice;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class AwtTest0 extends WindowAdapter implements ItemListener {
private Frame frame;
private Panel cards;
public void itemStateChanged(ItemEvent event) {
CardLayout layout = (CardLayout) cards.getLayout();
if (event.getStateChange() == ItemEvent.SELECTED) {
Object obj = event.getItem();
String name = obj.toString();
layout.show(cards, name);
}
}
public void windowClosing(WindowEvent event) {
System.exit(0);
}
private Panel createCard(String text) {
Panel card = new Panel();
Label label = new Label(text);
card.add(label);
return card;
}
private Panel createCards() {
cards = new Panel(new CardLayout());
cards.add(createCard("1"), "one");
cards.add(createCard("2"), "two");
cards.add(createCard("3"), "three");
return cards;
}
private Panel createChoice() {
Panel panel = new Panel();
Choice ch = new Choice();
ch.add("one");
ch.add("two");
ch.add("three");
ch.addItemListener(this);
panel.add(ch);
return panel;
}
private void showGui() {
frame = new Frame();
frame.addWindowListener(this);
frame.add(createChoice(), BorderLayout.PAGE_START);
frame.add(createCards(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
final AwtTest0 instance = new AwtTest0();
EventQueue.invokeLater(() -> instance.showGui());
}
}
In method main I call method invokeLater which explicitly launches the EDT (Event Dispatch Thread). The GUI must run on this thread.
In order to cause the application to terminate when you click the close window button (which is usually an X in the top corner of the window), you add a WindowListener.
When you add components to the Frame, you are actually adding them to the content pane which is a Panel that has BorderLayout layout manager.
Choice does not support ActionListener, it supports ItemListener. Hence the above code implements ItemListener.
Related
I am currently working on my school project to practice vocabulary, I have a method in my GUI that creates new vocabulary and the name of the list, I wanted to create a button that adds more Panels with input fields just this prototype image.
My idea is that when the user clicks
AddMoreButton it will add one JPanel just like P Panel, then the user can write vocabulary to send it to my database, is it possible to create something that?, I tried looping the P panel but it did not not change, any help would be appreciated.
private JPanel SetUpCreate() {
JPanel createPanel = new JPanel();
nameListInput = new JTextField(INPUT_FIELD_WIDTH);
termInput = new JTextField(INPUT_FIELD_WIDTH);
defintionInput = new JTextField(INPUT_FIELD_WIDTH);
p = new JPanel();
doneCreate = new JButton("Done");
doneCreate.addActionListener(new DoneCreateButtonAction());
addMoreButton = new JButton("Add");
addMoreButton.addActionListener(new AddMorePanelsListener());
p.setBorder(new BevelBorder(BevelBorder.RAISED));
p.add(termInput);
p.add(defintionInput);
JScrollPane pane = new JScrollPane(p);
createPanel.add(nameListInput);
createPanel.add(p);
createPanel.add(pane);
createPanel.add(doneCreate);
return createPanel;
}
private class DoneCreateButtonAction implements ActionListener {
public DoneCreateButtonAction() {
super();
}
public void actionPerformed(ActionEvent e) {
String namelist = nameListInput.getText();
String termglosa = termInput.getText();
String defintionglosa = defintionInput.getText();
try {
if (model.createWordList(namelist) && (model.createGlosa(termglosa, defintionglosa))) {
cl.show(cardPanel, "home");
}
} catch (IOException e1) {
JOptionPane.showMessageDialog(frame, "skapelsen av listan fungerar ej.");
}
}
}
private class AddMoreButtonAction implements ActionListener {
public AddMoreButtonAction() {
super();
}
public void actionPerformed(ActionEvent e) {
}
}
What I understand from your question is that you want to add another panel every time the user clicks the Add button and the panel to add contains fields for entering a word and its definition.
I see JScrollPane appears in the code you posted in your question. I think this is the correct implementation. In the below code, every time the user clicks the Add button I create a panel that contains the fields for a single word definition. This newly created panel is added to an existing panel that uses GridLayout with one column. Hence every time a new word definition panel is added, it is placed directly below the last word panel that was added and this GridLayout panel is placed inside a JScrollPane. Hence every time a word definition panel is added, the GridLayout panel height increases and the JScrollPane adjusts accordingly.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class MorPanel implements ActionListener, Runnable {
private static final String ADD = "Add";
private JFrame frame;
private JPanel vocabularyPanel;
#Override
public void run() {
showGui();
}
#Override
public void actionPerformed(ActionEvent actionEvent) {
String actionCommand = actionEvent.getActionCommand();
switch (actionCommand) {
case ADD:
vocabularyPanel.add(createWordPanel());
vocabularyPanel.revalidate();
vocabularyPanel.repaint();
break;
default:
JOptionPane.showMessageDialog(frame,
actionCommand,
"Unhandled",
JOptionPane.ERROR_MESSAGE);
}
}
public JButton createButton(String text) {
JButton button = new JButton(text);
button.addActionListener(this);
return button;
}
public JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(createButton(ADD));
return buttonsPanel;
}
private JScrollPane createMainPanel() {
vocabularyPanel = new JPanel(new GridLayout(0, 1));
vocabularyPanel.add(createWordPanel());
JScrollPane scrollPane = new JScrollPane(vocabularyPanel);
return scrollPane;
}
private JPanel createWordPanel() {
JPanel wordPanel = new JPanel();
JLabel wordLabel = new JLabel("Enter Term");
JTextField wordTextField = new JTextField(10);
JLabel definitionLabel = new JLabel("Enter Term Definition");
JTextField definitionTextField = new JTextField(10);
wordPanel.add(wordLabel);
wordPanel.add(wordTextField);
wordPanel.add(definitionLabel);
wordPanel.add(definitionTextField);
return wordPanel;
}
private void showGui() {
frame = new JFrame("Vocabulary");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.setSize(480, 200);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new MorPanel());
}
}
As your code is not an Minimal Reproducible Example, I cannot provide further assistance than this:
Red part: Your main JPanel with BoxLayout
Green part: another JPanel with your JTextField in it.
Purple part: JScrollPane
Blue parts: custom JPanels with 2 panes in them, one on top for the number, one on the bottom for both JTextFields and icon, so I would say GridBagLayout or BoxLayout + FlowLayout
Orange part: JPanel with GridBagLayout or FlowLayout
Each time you clic on the + icon, you just create a new instance of the custom blue JPanel and that's it.
I am writing some Java code that allows the user to see a frame with JLabel, JTextField and JButton.
I want the JLabel to be called "Count" and I have a problem with FlowLayout.
I want the interface to look like this:
Instead, I have this:
This is my code:
package modul1_Interfate_Grafice;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Exercitiu04 implements ActionListener {
private JFrame frame;
private JLabel labelCount;
private JTextField tfCount;
private JButton buttonCount;
private int count = 0;
public void go() {
frame = new JFrame("Java Counter");
labelCount = new JLabel("Counter");
labelCount.setLayout(new FlowLayout());
frame.getContentPane().add(BorderLayout.CENTER, labelCount);
tfCount = new JTextField(count + " ", 10);
tfCount.setEditable(false);
labelCount.add(tfCount);
buttonCount = new JButton("Count");
labelCount.add(buttonCount);
buttonCount.addActionListener(this);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(350, 150);
frame.setLocation(400, 200);
}
#Override
public void actionPerformed(ActionEvent event) {
count++;
tfCount.setText(count + "");
}
public static void main(String[] args) {
Exercitiu04 a = new Exercitiu04();
a.go();
}
}
Solve it.
Instead of labelCount.setLayout(new FlowLayout());` i should have had
frame.setLayout(new FlowLayout());
From description of JLabel class,
JLabel is:
A display area for a short text string or an image, or both.
But here: labelCount.add(tfCount) and here labelCount.add(buttonCount) you're trying to put a textfield and a button into a label. In this case, positions of button and textfield are controlled by FlowLayout but position of the text in the label is not.
Instead of this, you should put all of your elements in common JPanel, like this:
...
frame = new JFrame("Java Counter");
frame.setLayout(new BorderLayout());
JPanel wrapper = new JPanel(); // JPanel has FlowLayout by default
labelCount = new JLabel("Counter");
labelCount.setLayout(new FlowLayout());
wrapper.add(labelCount);
tfCount = new JTextField(count + " ", 10);
tfCount.setEditable(false);
wrapper.add(tfCount);
buttonCount = new JButton("Count");
buttonCount.addActionListener(this);
wrapper.add(buttonCount);
frame.add(BorderLayout.CENTER, wrapper);
...
And, like MasterBlaster said, you should put swing methods in EDT.
There are only two things you should know about FlowLayout:
a) It is a default layout manager of the JPanel component
b) It is good for nothing.
This trivial layout cannot be achieved with FlowLayout.
When doing layouts in Swing, you should familiarize yourself
with some powerful layout managers. I recommend MigLayout and
GroupLayout.
package com.zetcode;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
/*
Simple UI with a MigLayout manager.
Author Jan Bodnar
Website zetcode.com
*/
public class MigLayoutCounterEx extends JFrame {
public MigLayoutCounterEx() {
initUI();
}
private void initUI() {
JLabel lbl = new JLabel("Counter");
JTextField field = new JTextField(10);
JButton btn = new JButton("Count");
createLayout(lbl, field, btn);
setTitle("Java Counter");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void createLayout(JComponent... arg) {
setLayout(new MigLayout());
add(arg[0]);
add(arg[1]);
add(arg[2]);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MigLayoutCounterEx ex = new MigLayoutCounterEx();
ex.setVisible(true);
});
}
}
The example is trivial. You just put the three components into the
cells.
Screenshot:
You shouldn't use setSize when dealing with FlowLayout. Instead use pack(). It makes the window just about big enough to fit all your components in. That should tidy things up for you
I have a problem which is most likely "simple" however I can't figure it out. I am trying to reference my current JFrame so that I can dispose of it, and create a new one, thus "resetting" the program, however I and having trouble figuring out how to reference the JFrame, I have tried, super, this and getParent(), but none of the seem to work. Thanks for any / all help. ^^
Here is my code:
Main Class, just sets up the Jframe and calls the class that creates everything:
public static void main(String args[]) {
JFrame window = new JFrame();
Director director = new Director(window, args);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
window.pack();
window.setVisible(true);
}
}
Class the creates everything:
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class Director extends JFrame implements CollisionListener {
private BrickWall wall;
private JLabel gameTitle, gameScore, gameLives;
private JPanel controlPanel;
private JButton reset, quit;
private JRadioButton hard, normal, easy;
private int score = 6, lives = 5;
private ButtonGroup difficulty;
public Director(JFrame window, String[] args) {
window.getContentPane().add(makeGamePanel(), BorderLayout.CENTER);
window.getContentPane().add(gameControlPanel(), BorderLayout.NORTH);
}
public void collisionDetected(CollisionEvent e) {
wall.setBrick(e.getRow(), e.getColumn(), null);
}
private JComponent makeGamePanel() {
wall = new BrickWall();
wall.addCollisionListener(this);
wall.buildWall(3, 6, 1, wall.getColumns(), Color.GRAY);
return wall;
}
// Reset method I'm trying to dispose of the JFrame in.
private void reset() {
JFrame frame = new JFrame();
frame.getContentPane().add(makeGamePanel(), BorderLayout.CENTER);
frame.getContentPane().add(gameControlPanel(), BorderLayout.NORTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private JComponent gameControlPanel() {
// CONTROL PANEL PANEL!
controlPanel = new JPanel();
gameTitle = new JLabel("Brickles");
gameScore = new JLabel("Score:" + " " + score);
gameLives = new JLabel("Lives:" + " " + lives);
reset = new JButton("Reset");
quit = new JButton("Quit");
hard = new JRadioButton("Hard", false);
normal = new JRadioButton("Normal", true);
easy = new JRadioButton("Easy", false);
difficulty = new ButtonGroup();
difficulty.add(hard);
difficulty.add(normal);
difficulty.add(easy);
controlPanel.setLayout(new GridLayout(4, 2));
controlPanel.add(gameTitle);
controlPanel.add(gameScore);
controlPanel.add(hard);
controlPanel.add(gameLives);
controlPanel.add(normal);
controlPanel.add(reset);
controlPanel.add(easy);
controlPanel.add(quit);
// Action Listener, where I'm caling the reset method.
reset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
reset();
}
});
return controlPanel;
}
}
You can refer to the "outer this" from a nested class with the following syntax:
reset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Director.this.reset();
}
});
Yes, you can refer to the outer class by specifying it with the class name as noted in DSquare's good answer (1+ to it), but I urge you not to fling JFrame's at the user as you're program is trying to do. I recommend:
Instead of opening and closing multiple JFrames, use only one JFrame as the main application's window.
If you need helper windows, such as modal windows to get critical information that is absolutely needed, before the program can progress, use modal dialogs such as JDialogs or JOptionPanes.
If you need to swap GUI's, instead of swapping JFrames, swap "views" inside the JFrame via a CardLayout.
Gear your code towards creating these JPanel views and not JFrames as it will make your Swing GUI's much more flexible and portable.
For my homework extra credit I am creating a JTabbedPane and adding two Jpanels. I feel like I am very close, but it still does not compile. When I run it, both JPanels open, but the JTabbedPane does not. I get a lot of Unknown Source errors. I suspect that at this point my issue in in the JPanels themselves because they started out being JFrames and I have tried (unsuccessfully I think) to convert the JFrames to JPanels.
JTabbedPaneAssignment is supposed to create the JTabbedPane and populate the two panes with the apps DayGui on one tab and OfficeAreaCalculator on the other. I only include the JTabbedPaneAssignment and DayGui classes here. I apologize if its too much code, I have trimmed off a lot of what I consider extraneous, but there may still be too much.
Here is the calling class JTabbedPaneAssignment
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JTabbedPaneAssignment extends JPanel
{
public JTabbedPaneAssignment()
{
//super(new GridLayout(1, 1));
JTabbedPane tabbedPane = new JTabbedPane();
DayGui pnlDay = new DayGui();
OfficeAreaCalculator pnlOffice = new OfficeAreaCalculator ();
this.add(tabbedPane);
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
tabbedPane.add(panel1,"First panel");
tabbedPane.add(panel2,"Second panel");
//JComponent panel1 = makeTextPanel("Pane #1");
panel1.setPreferredSize(new Dimension(300, 150));
tabbedPane.addTab("DayGui", panel1);
tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
//JComponent panel2 = makeTextPanel("Pane #2");
panel2.setPreferredSize(new Dimension(410, 50));
tabbedPane.addTab("OfficeAreaCalculator", panel2);
tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
add(tabbedPane);
}
protected JComponent makeTextPanel(String text)
{
JPanel panel = new JPanel(false);
JLabel filler = new JLabel(text);
filler.setHorizontalAlignment(JLabel.CENTER);
panel.setLayout(new GridLayout(1, 1));
panel.add(filler);
return panel;
}
// Create JTabbedPane
private static void createAndShowGUI()
{
// Create and set up the window.
JFrame frame = new JFrame("JTabbedPane");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTabbedPaneAssignment(), BorderLayout.CENTER);
JTabbedPane DayGui = new JTabbedPane();
JTabbedPane OfficeAreaCalculator = new JTabbedPane();
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Here is DayGui class. It started out as a JFrame, but I am trying to convert it to a JPanel. I think my issue is in this section of code, but I don't know
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//public class DayGui extends JPanel
public class DayGui extends JPanel
{
private JPanel dayPanel;
private JButton cmdGood;
private JButton cmdBad;
public DayGui()
{
//dayPanel = new JPanel("Messages");
cmdGood = new JButton("Good");
cmdBad = new JButton("Bad");
Container c = dayPanel.getRootPane();
c.setLayout(new FlowLayout());
c.add(cmdGood);
c.add(cmdBad);
dayPanel.setSize(300, 150);
ButtonsHandler bhandler = new ButtonsHandler();
cmdGood.addActionListener(bhandler);
cmdBad.addActionListener(bhandler);
dayPanel.setVisible(true);
dayPanel.getRootPane().setBackground(Color.CYAN);
}
class ButtonsHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == cmdGood)
JOptionPane.showMessageDialog(null, "Today is a good day!",
"Event Handler Message",
JOptionPane.INFORMATION_MESSAGE);
if (e.getSource() == cmdBad)
JOptionPane.showMessageDialog(null, "Today is a bad day!",
"Event Handler Message",
JOptionPane.INFORMATION_MESSAGE);
}
}
}
You have been very ambiguous with your question, and you've posted way more code than anyone here has time to trawl through.
I've made a very small but working JTabbedPane example for you to see the smallest amount of work you need to get it working.
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
public class JTabbedPaneExample extends JFrame{
public JTabbedPaneExample(String title){
super(title);
setSize(800,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JTabbedPane tabbedPane = new JTabbedPane();
JPanel panelOne = new JPanel();
JPanel panelTwo = new JPanel();
tabbedPane.add(panelOne,"First panel");
tabbedPane.add(panelTwo,"Second panel");
add(tabbedPane);
}
public static void main(String[] args){
new JTabbedPaneExample("JTP Example").setVisible(true);
}
}
Then running, this code looks like:
If you repeat the same process in your code, and you've still got errors, then the problem is not with your JTabbedPane, but something else.
Okay, here goes a second time. Now you've got the DayGui class up, we notice that you're trying to use dayPanel before you've initialised it. i.e. nowhere do you say dayPanel = new JPanel();. This resulted in a NullPointerException being thrown in your code, screwing up your normal course of exection. Fix this and your DayGui class would run fine at runtime.
Among your codebase, you also do some very funky things, namely start using something but never getting around to finishing it up. An example of this is you extending JPanel, but resorting to using a member variable of type JPanel to do the rest of the work. The suggestion is to scrap the instance variable all together and use the methods you've inherited from extending JPanel.
Now lets move onto your JTabbedPaneAssignment class. Although not terrible, the code is not very readable and it repeats itself in many places (adding your tabbedpanel multiple times). If you were to take this code further into a larger project, maintenance and debugging would quickly become a problem.
For the purposes of showing you how much clutter you had in your code, I've quickly rewritten your provided code to be compilable, and should roughly do what you're working on.
JTabbedPaneAssignment:
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
public class JTabbedPaneAssignment extends JPanel
{
public JTabbedPaneAssignment()
{
final JTabbedPane tabbedPane = new JTabbedPane();
final DayPanel dayPanel = new DayPanel();
final JPanel officePanel = new JPanel();
tabbedPane.add("DayGui", dayPanel);
tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
tabbedPane.add("OfficeAreaCalculator", officePanel);
tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
add(tabbedPane);
}
// Create JTabbedPane
private static void createAndShowGUI()
{
// Create and set up the window.
JFrame frame = new JFrame("JTabbedPane");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTabbedPaneAssignment(), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
DayGui - renamed as DayPanel:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class DayPanel extends JPanel {
public DayPanel() {
super();
setBackground(Color.CYAN);
final JButton goodButton = new JButton("Good");
final JButton badButton = new JButton("Bad");
ActionListener listener = new DayPanel.ButtonsHandler();
goodButton.addActionListener(listener);
badButton.addActionListener(listener);
add(goodButton);
add(badButton);
}
class ButtonsHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
final String command = ((JButton) e.getSource()).getActionCommand();
if (command.equals("Good")) {
showMessage("Today is a good day!");
} else if (command.equals("Bad")) {
showMessage("Today is a bad day!");
}
}
// Show popup message
private void showMessage(String message) {
JOptionPane.showMessageDialog(null, message,
"Event Handler Message", JOptionPane.INFORMATION_MESSAGE);
}
}
}
So what is different in these? Basically, I've removed your NullPointerException you were getting in DayGui. Any other changes I've made are with the intention than you try and keep your code clutter free, so you really know what is going on in your code.
Hope this helps.
When I run it, both JPanels open, but the JTabbedPane does not. I get
a lot of Unknown Source errors.
Well, based on your code and your import section:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
This lines won't compile (unless DayGUI and OfficeAreaCalculator classes are in the same package than your JTabbedPaneAssignment class):
DayGui pnlDay = new DayGui();
OfficeAreaCalculator pnlOffice = new OfficeAreaCalculator ();
This is the only error I've got trying to compile and run your example. I changed lines below:
tabbedPane.addTab( "DayGui", new JPanel());
tabbedPane.addTab("Office Calculator", new JPanel());
And it worked like a charm.
Update
Based on your recent edit (adding your DayGui class, thank you) you have couple of mistakes in your code.
DayGui : this class extends of JPanel so you need to add your components directly on this class, you don't need this panel:
private JPanel dayPanel;
You need to set the layout manager, buttons and background directly on DayGuiclass, like this:
public DayGui() {
cmdGood = new JButton("Good");
cmdBad = new JButton("Bad");
setLayout(new FlowLayout());
add(cmdGood);
add(cmdBad);
setSize(300, 150);
ButtonsHandler bhandler = new ButtonsHandler();
cmdGood.addActionListener(bhandler);
cmdBad.addActionListener(bhandler);
setBackground(Color.CYAN);
}
JTabbedPaneAssignment : I think you're trying to add panel1 and panel2 as tabs but you use add method instead addTab:
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
tabbedPane.add(panel1,"First panel");
tabbedPane.add(panel2,"Second panel");
Also this line:
tabbedPane.addTab("DayGui", panel1);
Should be:
tabbedPane.addTab("DayGui", pnlDay);
Finally in this line you are adding panel2 for a second time and that's not correct:
tabbedPane.addTab("OfficeAreaCalculator", panel2); //I'd comment this line
If you make suggested changes you'll see something like this (BTW the CYAN color almost made me blind :P):
Hope this be helpful and sorry for the extension.
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