I'm trying to build a small inventory application in Java, that switches views (or pages) based on the card layout. For the standard change the user will use the menu at the top of the app, and that works fine.
But, one one of my screens the user will enter an item ID number to check. If that ID number is not found in the database, the app should switch to the New Item page. This is where I'm at a loss. I've tried to change the currently viewed card but nothing seems to be getting it.
Forgive me if this is a basic question (as well as poorly written Java :) ), I'm teaching myself Java as I write this app. Attached I'm adding part of the main class (InventoryTrackingSystem) and the GUI class (the one that is trying to change the view).
/***** The MAIN class **********/
package inventorytrackingsystem;
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.rmi.*;
public class InventoryTrackingSystem implements ItemListener {
JPanel mainPanel;
JFrame frame;
JPanel cards = new JPanel(new CardLayout());; //a panel that uses CardLayout
final static String MAINPANEL = "Main";
final static String CHECKITEMSPANEL = "Check Items";
final static String NEWITEMPANEL = "New Item";
final static String CHECKOUTITEMPANEL = "Check Out Item";
final static String ITEMINFOPANEL = "Item Information";
final static String LISTALLITEMSPANEL = "List All Items";
JPanel comboBoxPane;
private JComboBox cb;
static String comboBoxItems[] = {MAINPANEL,CHECKITEMSPANEL,NEWITEMPANEL,CHECKOUTITEMPANEL,ITEMINFOPANEL,LISTALLITEMSPANEL};
public static void main(String[] args) {
InventoryTrackingSystem ITS = new InventoryTrackingSystem();
/* Use an appropriate Look and Feel */
try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} catch (UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
/* Turn off metal's use of bold fonts */
UIManager.put("swing.boldMetal", Boolean.FALSE);
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
// javax.swing.SwingUtilities.invokeLater(new Runnable() {
// public void run() {
ITS.createAndShowGUI();
// }
// });
}
public void addComponentToPane(Container pane){
//Put the JComboBox in a JPanel to get a nicer look.
comboBoxPane = new JPanel(); //use FlowLayout
cb = new JComboBox(comboBoxItems);
cb.setEditable(false);
cb.addItemListener(this);
comboBoxPane.add(cb);
cb.setVisible(false);
//Create the "cards".
JPanel main = new guiBuilder().buildGui("main");
JPanel checkItems = new guiBuilder().buildGui("checkItems");
JPanel newItems = new guiBuilder().buildGui("newItems");
JPanel checkOutItems = new guiBuilder().buildGui("checkOutItems");
JPanel itemInfo = new guiBuilder().buildGui("itemInfo");
JPanel listAllItems = new guiBuilder().buildGui("listAllItems");
//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(main, MAINPANEL);
cards.add(checkItems, CHECKITEMSPANEL);
cards.add(newItems, NEWITEMPANEL);
cards.add(checkOutItems, CHECKOUTITEMPANEL);
cards.add(itemInfo, ITEMINFOPANEL);
cards.add(listAllItems, LISTALLITEMSPANEL);
pane.add(comboBoxPane, BorderLayout.PAGE_START);
pane.add(cards, BorderLayout.CENTER);
}
public void itemStateChanged(ItemEvent evt) {
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, (String)evt.getItem());
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event dispatch thread.
*/
private void createAndShowGUI() {
//Create and set up the window.
frame = new JFrame("Inventory Tracking System");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
Menu m1 = new Menu("Options");
MenuItem mi1_0 = new MenuItem("Main Page");
mi1_0.setActionCommand("main");
mi1_0.addActionListener(new menuListener());
MenuItem mi1_1 = new MenuItem("Check Item");
mi1_1.setActionCommand("checkItem");
mi1_1.addActionListener(new menuListener());
MenuItem mi1_2 = new MenuItem("Add New Item");
mi1_2.setActionCommand("addItem");
mi1_2.addActionListener(new menuListener());
MenuItem mi1_3 = new MenuItem("List All Items");
mi1_3.setActionCommand("listAllItems");
mi1_3.addActionListener(new menuListener());
MenuItem mi1_4 = new MenuItem("Check Out Item");
mi1_4.setActionCommand("checkOutItem");
mi1_4.addActionListener(new menuListener());
MenuItem mi1_5 = new MenuItem("Exit");
mi1_5.setActionCommand("exit");
mi1_5.addActionListener(new menuListener());
Menu m2 = new Menu("Help");
MenuItem mi2_0 = new MenuItem("About");
mi2_0.setActionCommand("about");
mi2_0.addActionListener(new menuListener());
m1.add(mi1_0);
m1.add(mi1_1);
m1.add(mi1_2);
m1.add(mi1_3);
m1.add(mi1_4);
m1.add(mi1_5);
m2.add(mi2_0);
MenuBar mb = new MenuBar();
frame.setMenuBar(mb);
mb.add(m1);
mb.add(m2);
//Create and set up the content pane.
//InventoryTrackingSystem setGUI = new InventoryTrackingSystem();
addComponentToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
frame.setSize(780, 830);
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we){
System.exit(0);
}
public void windowClosed(WindowEvent we){
System.exit(0);
}
});
}
class menuListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
String thisAction=ev.getActionCommand();
if(thisAction.equals("main")){
cb.setSelectedItem(MAINPANEL);
}else if(thisAction.equals("checkItem")){
//change GUI
cb.setSelectedItem(CHECKITEMSPANEL);
}else if(thisAction.equals("addItem")){
//change GUI
cb.setSelectedItem(NEWITEMPANEL);
}else if(thisAction.equals("checkOutItem")){
//change GUI
cb.setSelectedItem(CHECKOUTITEMPANEL);
}else if(thisAction.equals("listAllItems")){
//change GUI
cb.setSelectedItem(LISTALLITEMSPANEL);
}else if(thisAction.equals("exit")){
System.exit(0);
}else if(thisAction.equals("about")){
JOptionPane.showMessageDialog(frame, "About This App");
}
}
}
public void swapView(String s){
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, s);
}
}
/***** The GUI class **********/
package inventorytrackingsystem;
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.Image.*;
import java.awt.image.BufferedImage.*;
import javax.imageio.*;
import com.sun.jimi.core.*;
public class guiBuilder {
JLabel itemIdLabel;
JTextField itemID;
JButton checkIt;
JButton getSignature;
mySqlStuff sql=new mySqlStuff();
public JPanel buildGui(String guiType){
JPanel thisGUI;
if(guiType.equals("main")){
thisGUI=mainGUI();
}else if(guiType.equals("checkItems")){
thisGUI=checkItemsGUI();
}else if(guiType.equals("newItems")){
thisGUI=newItemsGUI();
}else if(guiType.equals("checkOutItems")){
thisGUI=checkOutItemsGUI();
}else if(guiType.equals("itemInfo")){
thisGUI=itemInfoGUI();
}else if(guiType.equals("listAllItems")){
thisGUI=listAllItemsGUI();
}else{
thisGUI=mainGUI();
}
return thisGUI;
} /* close buildGui() Method */
private JPanel mainGUI(){
JPanel thisPanel = new JPanel();
return thisPanel;
}
private JPanel checkItemsGUI(){
JPanel thisPanel = new JPanel();
JPanel itemSection=new JPanel();
JPanel exitSection=new JPanel();
itemIdLabel=new JLabel("Enter/Scan Item ID");
itemID=new JTextField(4);
itemID.addKeyListener(new myItemIdListener());
checkIt=new JButton("Check Item");
checkIt.addActionListener(new myItemCheckListener());
itemSection.add(itemIdLabel);
itemSection.add(itemID);
itemSection.add(checkIt);
JButton exitButton=new JButton("Exit");
exitButton.addActionListener(new exitButtonListener());
exitSection.add(exitButton);
thisPanel.add(itemSection);
thisPanel.add(exitSection);
return thisPanel;
}
private JPanel newItemsGUI(){
JPanel thisPanel = new JPanel();
return thisPanel;
}
private JPanel checkOutItemsGUI(){
JPanel thisPanel = new JPanel();
return thisPanel;
}
private JPanel itemInfoGUI(){
JPanel thisPanel = new JPanel();
return thisPanel;
}
private JPanel listAllItemsGUI(){
JPanel thisPanel = new JPanel();
return thisPanel;
}
class myItemIdListener implements KeyListener{
boolean keyGood=false;
public void keyPressed(KeyEvent keyEvent){
int keyCode=keyEvent.getKeyCode();
if((keyCode>=48 && keyCode<=57) || (keyCode>=96 && keyCode<=105)){
keyGood=true;
}
}
public void keyReleased(KeyEvent keyEvent){
int keyCode=keyEvent.getKeyCode();
if((keyCode>=48 && keyCode<=57) || (keyCode>=96 && keyCode<=105)){
printIt("Released",keyEvent);
}else if(keyCode==10){
checkIt.doClick();
}
}
public void keyTyped(KeyEvent keyEvent){
int keyCode=keyEvent.getKeyCode();
if((keyCode>=48 && keyCode<=57) || (keyCode>=96 && keyCode<=105)){
printIt("Typed",keyEvent);
}
}
private void printIt(String title,KeyEvent keyEvent){
int keyCode=keyEvent.getKeyCode();
String keyText=KeyEvent.getKeyText(keyCode);
String currentData;
if(title.equals("Pressed")){
keyGood=true;
}else if(title.equals("Released")){
System.out.println(title+ " -> "+keyCode+" / "+keyText);
}else if(title.equals("Typed")){
System.out.println(title+ " -> "+keyCode+" / "+keyText);
}
try{
String text=itemID.getText();
if(text.length()==4){
checkIt.doClick();
}else{
System.out.println("currentlLength: "+itemID.getText().length());
}
}catch(Exception ex){
ex.printStackTrace();
}
}
}
/**** THIS IS WHERE THE SWAP VIEW IS CALLED ****/
class myItemCheckListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
String itemNum=itemID.getText();
itemID.setText("");
System.out.println("Checking ID#: "+itemNum);
ArrayList checkData=new ArrayList(sql.checkInventoryData(itemNum));
if(checkData.get(0).toString().equals("[NULL]")){
System.out.println("New Item -> "+checkData.get(0).toString());
InventoryTrackingSystem ITS = new InventoryTrackingSystem();
ITS.swapView("NEWITEMPANEL");
}else{
System.out.println("Item Exists -> "+checkData.get(0).toString());
}
System.out.println(checkData);
}
}
class signaturePadButtonListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
signaturePadStuff signature = new signaturePadStuff();
while(signature.imageFileMoved==false){
// wait for the signature to be collected and the image moved to the server.
}
System.out.println(signature.newFileName);
}
}
class exitButtonListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
System.exit(0);
}
}
/** Returns an ImageIcon, or null if the path was invalid. */
protected ImageIcon createImageIcon(String path, String description) {
java.net.URL imgURL = getClass().getResource(path);
if(imgURL != null){
return new ImageIcon(imgURL, description);
}else{
System.err.println("Couldn't find file: " + path);
return null;
}
}
class submitItemButtonListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
String errorMsg = "";
String[] formResults = new String[25];
}
}
class clearFormButtonListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
return;
}
}
}
With this code in your actionPerformed method...
InventoryTrackingSystem ITS = new InventoryTrackingSystem();
ITS.swapView("NEWITEMPANEL");
...you are calling swapView on a new instance of InventoryTrackingSystem (which is not the one you created in main and for which the UI is showing on the screen).
-edited-
you need an instance of InventoryTrackingSystem in your action listener
you can for example store it in a member variable of myItemCheckListener like this:
class myItemCheckListener implements ActionListener{
private InventoryTrackingSystem its;
// constructor takes its instance as argument
public myItemCheckListener(InventoryTrackingSystem its){
// ...assigns it to the member variable
this.its = its;
}
public void actionPerformed(ActionEvent ev){
// call swapView on the correct instance of InventoryTrackingSystem
its.swapView()
}
}
Of course, since your action listener is created in guiBuilder.buildGui() / checkItemsGUI() you will need the ITS instance there, too.
BTW:
It is not really necessary to create new guiBuilder instances like this:
JPanel main = new guiBuilder().buildGui("main");
...
JPanel listAllItems = new guiBuilder().buildGui("listAllItems");
instead you could:
guiBuilder builder = new guiBuilder();
builder.buildGui("main");
builder.build("whatever");
Related
So I'm working on making a database system built on top of a Java Swing GUI... I have one button that works to add a person/thing to a vector (in this case the database):
// Database
Vector<String> db = new Vector<String>();
Here is the button's actionlistener to add:
new ActionListener() {
public void actionPerformed(ActionEvent e) {
String newStudent = student.getText();
db.addElement(newStudent);
This part all seems to be working fine, however, when I go to print out the vector on a JTextArea using a string buffer, there are odd spacing issues in the text on the JTextArea
Here is the StringBuffer and section where I print the vector onto the JTextArea:
StringBuffer dbb = new StringBuffer();
for (int i = 0; i < db.size(); i++) {
dbb.append(db.get(i) + '\n');
}
// printDB is the JTextArea
printDB.setText(dbb.toString());
add(printDB);
Screenshot of spacing issues:
Screenshot
Any Ideas on what might be causing this? The spacing seems to be linear as well (1space, 2spaces, 3spaces...)
Link to full project if needed (Sorry for bad code in general lol i'm just beginning): Full Code
Sorry if linear isn't the right word btw I couldn't think of another way to describe it
Code:
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.*;
import java.util.Vector.*;
import javax.swing.*;
public class Database extends JFrame implements ActionListener, EventListener {
// Database
Vector<String> db = new Vector<String>();
// Main Menu Buttons:
JButton addStudent = new JButton("Add Student");
JButton deleteStudent = new JButton("Delete Button");
JButton deleteAll = new JButton("Delete All Students");
JButton printAll = new JButton("Print Database");
JTextArea welcome = new JTextArea("Welcome!");
// Add Student Menu:
JTextField student = new JTextField();
JButton submit = new JButton("Add Student");
// Print Students
JTextArea printDB = new JTextArea();
JButton returnMenu = new JButton("Return to Menu");
public Database() {
super("DatabaseGUI");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
setResizable(false);
welcome.setBackground(this.getForeground());
add(welcome);
welcome.setSize(60, 15);
welcome.setLocation(386, 300);
add(addStudent);
addStudent.setSize(150, 50);
addStudent.setLocation(25, 100);
add(deleteStudent);
deleteStudent.setSize(150, 50);
deleteStudent.setLocation(625, 100);
add(deleteAll);
deleteAll.setLocation(225, 100);
deleteAll.setSize(150, 50);
add(printAll);
printAll.setLocation(425, 100);
printAll.setSize(150, 50);
addStudent.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
welcome.setVisible(false);
addStudent.setVisible(false);
deleteStudent.setVisible(false);
deleteAll.setVisible(false);
printAll.setVisible(false);
add(student);
add(submit);
submit.setVisible(true);
submit.setSize(150, 30);
submit.setLocation(425, 250);
student.setVisible(true);
student.setSize(150, 30);
student.setLocation(275, 250);
submit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String newStudent = student.getText();
db.addElement(newStudent);
student.setText(null);
student.setVisible(false);
submit.setVisible(false);
welcome.setVisible(true);
addStudent.setVisible(true);
deleteStudent.setVisible(true);
deleteAll.setVisible(true);
printAll.setVisible(true);
}
});
}
});
printAll.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
welcome.setVisible(false);
addStudent.setVisible(false);
deleteStudent.setVisible(false);
deleteAll.setVisible(false);
printAll.setVisible(false);
StringBuffer dbb = new StringBuffer();
for (int i = 0; i < db.size(); i++) {
dbb.append(db.get(i) + '\n');
}
printDB.setText(dbb.toString());
add(printDB);
printDB.setSize(300, 400);
printDB.setEditable(false);
printDB.setLocation(100, 100);
printDB.setVisible(true);
add(returnMenu);
returnMenu.setVisible(true);
returnMenu.setSize(200, 30);
returnMenu.setLocation(500, 400);
returnMenu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
returnMenu.setVisible(false);
printDB.setVisible(false);
welcome.setVisible(true);
addStudent.setVisible(true);
deleteStudent.setVisible(true);
deleteAll.setVisible(true);
printAll.setVisible(true);
}
});
}
});
setVisible(true);
}
public static void main(String[] args) {
Database student = new Database();
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
You're adding an ActionListener to the submit button repeatedly within the addStudent ActionListener, meaning as addStudent is pressed, more and more ActionListeners will be added to submit and this is not what you want.
Suggestions:
Add an ActionListener just once to your JButtons and not within other event listeners which may be called multiple times. Consider adding all ActionListeners within your class constructor.
Side recs:
Don't use absolute positioning and null layouts. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
Learn how to use and then use CardLayout to allow you to cleanly and easily swap your views.
For example,
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class Database2 extends JPanel {
// constants for the cards
public static final String WELCOME = "welcome";
public static final String ADD_STUDENT = "add student";
public static final String DISPLAY_DATA = "display data";
private JTextArea displayTextArea = new JTextArea(15, 20);
private JTextField addStudentField = new JTextField(10);
private CardLayout cardLayout = new CardLayout();
private List<String> db = new ArrayList<>();
public Database2() {
// prepare JTextArea
displayTextArea.setWrapStyleWord(true);
displayTextArea.setLineWrap(true);
displayTextArea.setFocusable(false);
// set layout as CardLayout and add all JPanels with constants
setLayout(cardLayout);
add(createWelcomePanel(), WELCOME);
add(createAddStudentPanel(), ADD_STUDENT);
add(createDisplayDataPanel(), DISPLAY_DATA);
}
private JPanel createWelcomePanel() {
ShowStudentPanelAction showStudentAction = new ShowStudentPanelAction("Add Student");
DisplayDataAction displayDataAction = new DisplayDataAction("Display Data");
JButton addStudentButton = new JButton(showStudentAction);
JButton displayDataButton = new JButton(displayDataAction);
JPanel topPanel = new JPanel(new GridLayout(1, 0, 5, 0));
topPanel.add(addStudentButton);
topPanel.add(displayDataButton);
topPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));
JLabel welcomeLabel = new JLabel("Welcome", SwingConstants.CENTER);
// make JLabel text bigger
welcomeLabel.setFont(welcomeLabel.getFont().deriveFont(Font.BOLD, 42f));
// and give it a border 30 points wide
int ebGap = 30;
welcomeLabel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap,
ebGap, ebGap));
JPanel welcomePanel = new JPanel(new BorderLayout());
ebGap = 4;
welcomePanel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
welcomePanel.add(topPanel, BorderLayout.PAGE_START);
welcomePanel.add(welcomeLabel, BorderLayout.CENTER);
return welcomePanel;
}
private JPanel createAddStudentPanel() {
AddStudentAction addStudentAction = new AddStudentAction("Add Student");
addStudentField.setAction(addStudentAction);
JPanel addStudentPanel = new JPanel();
addStudentPanel.add(addStudentField);
addStudentPanel.add(new JButton(addStudentAction));
return addStudentPanel;
}
private JPanel createDisplayDataPanel() {
JPanel displayDataPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(displayTextArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
displayDataPanel.add(scrollPane);
displayDataPanel.add(new JButton(new ReturnToWelcomeAction("Return")));
return displayDataPanel;
}
private class ShowStudentPanelAction extends AbstractAction {
public ShowStudentPanelAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(Database2.this, ADD_STUDENT);
addStudentField.requestFocusInWindow();
addStudentField.selectAll();
}
}
private class DisplayDataAction extends AbstractAction {
public DisplayDataAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
StringBuilder sb = new StringBuilder();
for (String studentName : db) {
sb.append(studentName + "\n");
}
displayTextArea.setText(sb.toString());
cardLayout.show(Database2.this, DISPLAY_DATA);
}
}
private class AddStudentAction extends AbstractAction {
public AddStudentAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
String studentText = addStudentField.getText();
db.add(studentText);
cardLayout.show(Database2.this, WELCOME);
}
}
private class ReturnToWelcomeAction extends AbstractAction {
public ReturnToWelcomeAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(Database2.this, WELCOME);
}
}
private class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Window window = SwingUtilities.getWindowAncestor(Database2.this);
if (window != null) {
window.dispose();
}
}
}
private static void createAndShowGui() {
Database2 mainPanel = new Database2();
JFrame frame = new JFrame("Database2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I have created 2 classes that are working together to show pictures by clicking different buttons. In my EventEvent class I tried to make it so that when you press the "Picture 1" button, the variable ImageIcon xpic gets the value of ImageIcon vpic (which holds an image), after xpic has the same value as vpic my frame is supposed to somehow refresh so that xpic's new value applies and gets then shows the picture.
Why doesn't my image show up even though the button press repaints the JPanel the image is in?
Main class:
import java.awt.*;
import javax.swing.*;
public class EventMain extends JFrame{
EventEvent obje = new EventEvent(this);
// Build Buttons
JButton picB1;
JButton picB2;
JButton picB3;
JButton picB4;
JButton picB5;
//Build Panels
JPanel row0;
//Build Pictures
ImageIcon xpic;
ImageIcon vpic;
public EventMain(){
super("Buttons");
setLookAndFeel();
setSize(470, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridLayout layout1 = new GridLayout(3,4);
setLayout(layout1);
picB1 = new JButton("Picture 1");
picB2 = new JButton("Picture 2");
picB3 = new JButton("Picture 3");
picB4 = new JButton("Picture 4");
picB5 = new JButton("Picture 5");
vpic = new ImageIcon(getClass().getResource("Images/vanessa.png"));
// Set up Row 0
row0 = new JPanel();
JLabel statement = new JLabel("Choose a picture: ", JLabel.LEFT);
JLabel picture = new JLabel(xpic);
// Set up Row 1
JPanel row1 = new JPanel();
// Set up Row 2
JPanel row2 = new JPanel();
//Listeners
picB1.addActionListener(obje);
FlowLayout grid0 = new FlowLayout (FlowLayout.CENTER);
row0.setLayout(grid0);
row0.add(statement);
row0.add(picture);
add(row0);
FlowLayout grid1 = new FlowLayout(FlowLayout.CENTER);
row1.setLayout(grid1);
row1.add(picB1);
row1.add(picB2);
add(row1);
FlowLayout grid2 = new FlowLayout(FlowLayout.CENTER);
row2.setLayout(grid2);
row2.add(picB3);
row2.add(picB4);
row2.add(picB5);
add(row2);
setVisible(true);
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.NimbusLookAndFeel");
} catch (Exception exc) {
}
}
public static void main(String[] args) {
EventMain con = new EventMain();
}
}
Class containing events:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EventEvent implements ActionListener {
EventMain gui;
public EventEvent(EventMain in){
gui = in;
}
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
if (command.equals("Picture 1")){
gui.xpic = gui.vpic;
gui.row0.repaint();
}
}
}
You're confusing variables with objects. Just because you change the object associated with the xpic variable, don't assume that this will change the object (the Icon) held by the JLabel. There is no magic in Java, and changing the object that a variable refers to will have no effect on the prior object.
In other words, this:
gui.xpic = gui.vpic;
gui.row0.repaint();
will have no effect on the icon that the picture JLabel is displaying
To swap icons, you must call setIcon(...) on the JLabel. Period. You will need to make the picture JLabel a field, not a local variable, and give your GUI class a public method that allows outside classes to change the state of the JLabel's icon.
Also, you should not manipulate object fields directly. Instead give your gui public methods that your event object can call.
Edit
For example:
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class MyGui extends JPanel {
public static final String IMAGE_PATH = "https://duke.kenai.com/cards/.Midsize/CardFaces.png.png";
private static final int ROWS = 4;
private static final int COLS = 13;
private BufferedImage largeImg;
private List<ImageIcon> iconList = new ArrayList<>();
private JLabel pictureLabel = new JLabel();
private JButton swapPictureBtn = new JButton(new SwapPictureAction(this, "Swap Picture"));
private int iconIndex = 0;
public MyGui() throws IOException {
add(pictureLabel);
add(swapPictureBtn);
URL imgUrl = new URL(IMAGE_PATH);
largeImg = ImageIO.read(imgUrl);
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
int x = (j * largeImg.getWidth()) / COLS;
int y = (i * largeImg.getHeight()) / ROWS;
int w = largeImg.getWidth() / COLS;
int h = largeImg.getHeight() / ROWS;
iconList.add(new ImageIcon(largeImg.getSubimage(x, y, w, h)));
}
}
pictureLabel.setIcon(iconList.get(iconIndex));
}
public void swapPicture() {
iconIndex++;
iconIndex %= iconList.size();
pictureLabel.setIcon(iconList.get(iconIndex));
}
private static void createAndShowGui() {
MyGui mainPanel;
try {
mainPanel = new MyGui();
JFrame frame = new JFrame("MyGui");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class SwapPictureAction extends AbstractAction {
private MyGui myGui;
public SwapPictureAction(MyGui myGui, String name) {
super(name);
this.myGui = myGui;
}
#Override
public void actionPerformed(ActionEvent e) {
myGui.swapPicture();
}
}
See the createAction() method below and how it creates an AbstractAction. See also the tutorial related to using actions with buttons. http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html
import javax.swing.*;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import java.awt.*;
import java.awt.event.ActionEvent;
public class EventMain {
private static final ImageIcon PICTURE_1 = new ImageIcon(EventMain.class.getResource("images/v1.png"));
private static final ImageIcon PICTURE_2 = new ImageIcon(EventMain.class.getResource("images/v2.png"));
private JFrame frame;
EventMain create() {
setLookAndFeel();
frame = createFrame();
frame.getContentPane().add(createContent());
return this;
}
void show() {
frame.setSize(470, 300);
frame.setVisible(true);
}
private JFrame createFrame() {
JFrame frame = new JFrame("Buttons");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
return frame;
}
private Component createContent() {
final JLabel picture = new JLabel();
JButton picB1 = new JButton(createAction("Picture 1", picture, PICTURE_1));
JButton picB2 = new JButton(createAction("Picture 2", picture, PICTURE_2));
JButton picB3 = new JButton(createAction("Picture 3", picture, PICTURE_1));
JButton picB4 = new JButton(createAction("Picture 4", picture, PICTURE_2));
JButton picB5 = new JButton(createAction("Picture 5", picture, PICTURE_1));
JLabel statement = new JLabel("Choose a picture: ", JLabel.LEFT);
// Create rows 1, 2, 3
JPanel panel = new JPanel(new GridLayout(3, 4));
panel.add(createRow(statement, picture));
panel.add(createRow(picB1, picB2));
panel.add(createRow(picB3, picB4, picB5));
return panel;
}
/**
* Create an action for the button. http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html
*/
private Action createAction(String label, final JLabel picture, final Icon icon) {
AbstractAction action = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
picture.setIcon(icon);
}
};
action.putValue(Action.NAME, label);
return action;
}
private Component createRow(Component... componentsToAdd) {
JPanel row = new JPanel(new FlowLayout(FlowLayout.CENTER));
for (Component component : componentsToAdd) {
row.add(component);
}
return row;
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel(new NimbusLookAndFeel());
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new EventMain().create().show();
}
});
}
}
Sorry if I'm double positing but I totally suck at Java.
I am trying to make my form have the ability to change dynamically if you select a radio button. The functions save, delete, new will remain the same but the contents of the body e.g. the UPC will change to ISBN of the novel and the other fields.
Is there a way to when you press Novel to load the items from Novel to replace Comic book items?
I tried to separate but I've hit a block and with my limited skills unsure what to do.
I just want it to be able to change it so that it works.
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.MenuBar;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;
public class FormFictionCatelogue extends JFrame implements ActionListener {
// Constants
// =========
private final String FORM_TITLE = "Fiction Adiction Catelogue";
private final int X_LOC = 400;
private final int Y_LOC = 80;
private final int WIDTH = 600;
private final int HEIGHT = 450;
private String gradeCode;
//final static String filename = "data/comicBookData.txt";
private JButton firstPageButton;
private JButton backPageButton;
private JButton forwardPageButton;
private JButton lastPageButton;
private JRadioButton comicBookRadioButton;
private JRadioButton novelRadioButton;
private final String FIRSTPAGE_BUTTON_TEXT = "|<";
private final String BACKPAGE_BUTTON_TEXT = "<";
private final String FORWARDPAGE_BUTTON_TEXT = ">";
private final String LASTPAGE_BUTTON_TEXT = ">|";
private final String COMICBOOK_BUTTON_TEXT = "Comic";
private final String NOVEL_BUTTON_TEXT = "Novel";
private final String SAVE_BUTTON_TEXT = "Save";
private final String EXIT_BUTTON_TEXT = "Exit";
private final String CLEAR_BUTTON_TEXT = "Clear";
private final String FIND_BUTTON_TEXT = "Find";
private final String DELETE_BUTTON_TEXT = "Delete";
private final String ADDPAGE_BUTTON_TEXT = "New";
// Attributes
private JTextField upcTextField;
private JTextField isbnTextField;
private JTextField titleTextField;
private JTextField issueNumTextField;
private JTextField bookNumTextField;
private JTextField writerTextField;
private JTextField authorTextField;
private JTextField artistTextField;
private JTextField publisherTextField;
private JTextField seriesTextField;
private JTextField otherBooksTextField;
private JTextField gradeCodeTextField;
private JTextField charactersTextField;
private JButton saveButton;
private JButton deleteButton;
private JButton findButton;
private JButton clearButton;
private JButton exitButton;
private JButton addPageButton;
FictionCatelogue fc;
/**
* #param args
* #throws Exception
*/
public static void main(String[] args) {
try {
FormFictionCatelogue form = new FormFictionCatelogue();
form.fc = new FictionCatelogue();
form.setVisible(true);
//comicBook selected by default
form.populatefields(form.fc.returnComic(0));
//if novel is selected change fields to novel and populate
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
/**
*
*/
public FormFictionCatelogue() {
// Set form properties
// ===================
setTitle(FORM_TITLE);
setSize(WIDTH, HEIGHT);
setLocation(X_LOC, Y_LOC);
// Create and set components
// -------------------------
// Create panels to hold components
JPanel menuBarPanel = new JPanel();
JPanel fieldsPanel = new JPanel();
JPanel buttonsPanel = new JPanel();
JPanel navigationPanel = new JPanel();
//JPanel radioButtonsPanel = new JPanel();
ButtonGroup bG = new ButtonGroup();
// Set the layout of the panels
GridLayout fieldsPanelLayout = new GridLayout(9, 6);
// Menu
JMenuBar menubar = new JMenuBar();
ImageIcon icon = new ImageIcon("exit.png");
JMenu file = new JMenu("File");
file.setMnemonic(KeyEvent.VK_F);
JMenu about = new JMenu("About");
file.setMnemonic(KeyEvent.VK_F);
JMenuItem eMenuItem = new JMenuItem("Exit", icon);
eMenuItem.setMnemonic(KeyEvent.VK_E);
eMenuItem.setToolTipText("Exit application");
eMenuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
JMenuItem eMenuItem1 = new JMenuItem("Reports", icon);
eMenuItem.setMnemonic(KeyEvent.VK_E);
eMenuItem.setToolTipText("Reports are located here");
eMenuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
//calls reports
//System.exit(0);
}
});
file.add(eMenuItem);
about.add(eMenuItem1);
menubar.add(file);
menubar.add(about);
setJMenuBar(menubar);
setTitle("Menu");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
//if comic is selected
ComicBookFields(fieldsPanel);
//else
//NovelFields(fieldsPanel);
// Buttons
comicBookRadioButton = new JRadioButton(COMICBOOK_BUTTON_TEXT);
novelRadioButton = new JRadioButton(NOVEL_BUTTON_TEXT);
bG.add(comicBookRadioButton);
bG.add(novelRadioButton);
this.setLayout(new FlowLayout());
this.add(comicBookRadioButton);
this.add(novelRadioButton);
comicBookRadioButton.setSelected(true);
bG.add(comicBookRadioButton);
bG.add(novelRadioButton);
addPageButton = new JButton(ADDPAGE_BUTTON_TEXT);
buttonsPanel.add(addPageButton);
saveButton = new JButton(SAVE_BUTTON_TEXT);
buttonsPanel.add(saveButton);
clearButton = new JButton(CLEAR_BUTTON_TEXT);
buttonsPanel.add(clearButton);
deleteButton = new JButton(DELETE_BUTTON_TEXT);
buttonsPanel.add(deleteButton);
findButton = new JButton(FIND_BUTTON_TEXT);
buttonsPanel.add(findButton);
exitButton = new JButton(EXIT_BUTTON_TEXT);
buttonsPanel.add(exitButton);
firstPageButton = new JButton(FIRSTPAGE_BUTTON_TEXT);
navigationPanel.add(firstPageButton);
backPageButton = new JButton(BACKPAGE_BUTTON_TEXT);
navigationPanel.add(backPageButton);
forwardPageButton = new JButton(FORWARDPAGE_BUTTON_TEXT);
navigationPanel.add(forwardPageButton);
lastPageButton = new JButton(LASTPAGE_BUTTON_TEXT);
navigationPanel.add(lastPageButton);
// Get the container holding the components of this class
Container con = getContentPane();
// Set layout of this class
con.setLayout(new BorderLayout());
con.setLayout( new FlowLayout());
// Add the fieldsPanel and buttonsPanel to this class.
// con.add(menuBarPanel, BorderLayout);
con.add(fieldsPanel, BorderLayout.CENTER);
con.add(buttonsPanel, BorderLayout.LINE_END);
con.add(navigationPanel, BorderLayout.SOUTH);
//con.add(radioButtonsPanel, BorderLayout.PAGE_START);
// Register listeners
// ==================
// Register action listeners on buttons
saveButton.addActionListener(this);
clearButton.addActionListener(this);
deleteButton.addActionListener(this);
findButton.addActionListener(this);
exitButton.addActionListener(this);
firstPageButton.addActionListener(this);
backPageButton.addActionListener(this);
forwardPageButton.addActionListener(this);
lastPageButton.addActionListener(this);
addPageButton.addActionListener(this);
comicBookRadioButton.addActionListener(this);
novelRadioButton.addActionListener(this);
// Exit program when window is closed
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public void Radiobutton (){
this.add(comicBookRadioButton);
this.add(novelRadioButton);
comicBookRadioButton.setSelected(true);
this.setVisible(true);
}
// Populate the fields at the start of the application
public void populatefields(ComicBook cb) {
String gradecode;
// radio button selection = comic do this
if (cb != null) {
upcTextField.setText(cb.getUpc());
titleTextField.setText(cb.getTitle());
issueNumTextField.setText(Integer.toString(cb.getIssuenumber()));
writerTextField.setText(cb.getWriter());
artistTextField.setText(cb.getArtist());
publisherTextField.setText(cb.getPublisher());
gradecode = cb.getGradeCode();
gradeCodeTextField.setText(cb.determineCondition(gradecode));
charactersTextField.setText(cb.getCharacters());
}
//radio button selection = novel do this
// Exit program when window is closed
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
/**
*
*/
public void actionPerformed(ActionEvent ae) {
try {
if(ae.getActionCommand().equals(COMICBOOK_BUTTON_TEXT)){
//FormFictionCatelogue form = new FormFictionCatelogue();
//form.populatefields(form.fc.returnObject(0));
//ComicBookFields(fieldsPanel);
populatefields(fc.returnComic(0));
} else if (ae.getActionCommand().equals(NOVEL_BUTTON_TEXT)) {
} else if (ae.getActionCommand().equals(SAVE_BUTTON_TEXT)) {
save();
} else if (ae.getActionCommand().equals(CLEAR_BUTTON_TEXT)) {
clear();
} else if (ae.getActionCommand().equals(ADDPAGE_BUTTON_TEXT)) {
add();
} else if (ae.getActionCommand().equals(DELETE_BUTTON_TEXT)) {
delete();
} else if (ae.getActionCommand().equals(FIND_BUTTON_TEXT)) {
find();
} else if (ae.getActionCommand().equals(EXIT_BUTTON_TEXT)) {
exit();
} else if (ae.getActionCommand().equals(FIRSTPAGE_BUTTON_TEXT)) {
// first record
populatefields(fc.firstRecord());
} else if (ae.getActionCommand().equals(FORWARDPAGE_BUTTON_TEXT)) {
// next record
populatefields(fc.nextRecord());
} else if (ae.getActionCommand().equals(BACKPAGE_BUTTON_TEXT)) {
// previous record
populatefields(fc.previousRecord());
} else if (ae.getActionCommand().equals(LASTPAGE_BUTTON_TEXT)) {
// last record
populatefields(fc.lastRecord());
} else {
throw new Exception("Unknown event!");
}
} catch (Exception e) {
JOptionPane.showMessageDialog(this, e.getMessage(), "Error!",
JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}
void clear() {
upcTextField.setText("");
titleTextField.setText("");
issueNumTextField.setText("");
writerTextField.setText("");
artistTextField.setText("");
gradeCodeTextField.setText("");
publisherTextField.setText("");
charactersTextField.setText("");
}
private void exit() {
System.exit(0);
}
void add() {
try{
clear();
ComicBook cb = new ComicBook();
fc.add(cb);
fc.lastRecord();
} catch (Exception e){
e.printStackTrace();
}
}
void save() throws Exception {
// if radio button = comic do this
ComicBook cb = new ComicBook();
String condition;
if (upcTextField.getText().length() == 16) {
//searches if there is another record if()
cb.setUpc(upcTextField.getText());
} else {
throw new Exception("Upc is not at required length ");
}
cb.setTitle(titleTextField.getText());
cb.setIssuenumber(Integer.parseInt(issueNumTextField.getText()));
cb.setWriter(writerTextField.getText());
cb.setArtist(artistTextField.getText());
cb.setPublisher(publisherTextField.getText());
condition = cb.determineString(gradeCodeTextField.getText());
if (condition.equals("Wrong Input")) {
throw new Exception("Grade code is not valid");
} else {
cb.setGradeCode(condition);
}
cb.setCharacters(charactersTextField.getText());
fc.save(cb);
// if radio button = novels do this
}
private void delete() throws Exception {
fc.delete();
populatefields(fc.getCurrentRecord());
}
private void find() {
// from
// http://www.roseindia.net/java/example/java/swing/ShowInputDialog.shtml
String str = JOptionPane.showInputDialog(null, "Enter some text : ",
"Comic Book Search", 1);
if (str != null) {
ComicBook cb = new ComicBook();
cb = fc.search(str);
if (cb != null) {
populatefields(cb);
} else {
JOptionPane.showMessageDialog(null, "No comic books found ",
"Comic Book Search", 1);
}
}
}
public JPanel ComicBookFields(JPanel fieldsPanel) {
// Create components and add to panels for ComicBook
GridLayout fieldsPanelLayout = new GridLayout(9, 6);
fieldsPanel.setLayout(fieldsPanelLayout);
fieldsPanel.add(new JLabel("UPC: "));
upcTextField = new JTextField(20);
fieldsPanel.add(upcTextField);
fieldsPanel.add(new JLabel("Title: "));
titleTextField = new JTextField(20);
fieldsPanel.add(titleTextField);
fieldsPanel.add(new JLabel("Issue Number: "));
issueNumTextField = new JTextField(20);
fieldsPanel.add(issueNumTextField);
fieldsPanel.add(new JLabel("Writer: "));
writerTextField = new JTextField(20);
fieldsPanel.add(writerTextField);
fieldsPanel.add(new JLabel("Artist: "));
artistTextField = new JTextField(20);
fieldsPanel.add(artistTextField);
fieldsPanel.add(new JLabel("Publisher: "));
publisherTextField = new JTextField(20);
fieldsPanel.add(publisherTextField);
fieldsPanel.add(new JLabel("Grade Code: "));
gradeCodeTextField = new JTextField(20);
fieldsPanel.add(gradeCodeTextField);
fieldsPanel.add(new JLabel("Characters"));
charactersTextField = new JTextField(20);
fieldsPanel.add(charactersTextField);
return fieldsPanel;
}
public JPanel NovelFields(JPanel fieldsPanel) {
// Create components and add to panels for ComicBook
GridLayout fieldsPanelLayout = new GridLayout(9, 6);
fieldsPanel.setLayout(fieldsPanelLayout);
fieldsPanel.add(new JLabel("ISBN: "));
isbnTextField = new JTextField(20);
fieldsPanel.add(isbnTextField);
fieldsPanel.add(new JLabel("Title: "));
titleTextField = new JTextField(20);
fieldsPanel.add(titleTextField);
fieldsPanel.add(new JLabel("Book Number: "));
bookNumTextField = new JTextField(20);
fieldsPanel.add(bookNumTextField);
fieldsPanel.add(new JLabel("Author: "));
authorTextField = new JTextField(20);
fieldsPanel.add(authorTextField);
fieldsPanel.add(new JLabel("Publisher: "));
publisherTextField = new JTextField(20);
fieldsPanel.add(publisherTextField);
fieldsPanel.add(new JLabel("Series: "));
seriesTextField = new JTextField(20);
fieldsPanel.add(seriesTextField);
fieldsPanel.add(new JLabel("Other Books"));
otherBooksTextField = new JTextField(20);
fieldsPanel.add(otherBooksTextField);
return fieldsPanel;
}
}
To swap forms you can use a CardLayout.
Read the section from the Swing tutorial on How to Use CardLayout for more information and working examples.
The example from the tutorial switches when you make a selection from a combo box. In your case you would change the panel when you click on the radio button. So you might also want to read the section from the tutorial on How to Use Buttons.
Otherwise you can switch JPanels on JRadioButton selection like this:
You've got a JPanel called displayPanel which contains the ComicPanel by default, if you select the Novel RadioButton the displayPanel gets cleared and the NovelPanel will be added.
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.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class AddNovelOrComicPanel extends JPanel implements ActionListener {
private JPanel selectPanel;
private JPanel displayPanel;
private JPanel buttonPanel;
private JRadioButton comic;
private JRadioButton novel;
// we need this ButtonGroup to take care about unselecting the former selected JRadioButton
ButtonGroup radioButtons;
public AddNovelOrComicPanel() {
this.setLayout(new BorderLayout());
initComponents();
this.add(selectPanel, BorderLayout.NORTH);
this.add(displayPanel, BorderLayout.CENTER);
}
/**
* Initializes all Components
*/
private void initComponents() {
selectPanel = new JPanel(new GridLayout(1, 2));
comic = new JRadioButton("Comic");
comic.setSelected(true);
comic.addActionListener(this);
novel = new JRadioButton("Novel");
novel.addActionListener(this);
radioButtons = new ButtonGroup();
radioButtons.add(comic);
radioButtons.add(novel);
selectPanel.add(comic);
selectPanel.add(novel);
displayPanel = new JPanel();
displayPanel.add(new ComicPanel());
}
#Override
public void actionPerformed(ActionEvent e) {
// if comic is selected show the ComicPanel in the displayPanel
if(e.getSource().equals(comic)) {
displayPanel.removeAll();
displayPanel.add(new ComicPanel());
}
// if novel is selected show the NovelPanel in the displayPanel
if(e.getSource().equals(novel)) {
displayPanel.removeAll();
displayPanel.add(new NovelPanel());
}
// revalidate all to show the changes
revalidate();
}
}
/**
* The NovelPanel class
* it contains all the Items you need to register a new Novel
*/
class NovelPanel extends JPanel {
public NovelPanel() {
this.add(new JLabel("Add your Novel components here"));
}
}
/**
* The ComicPanel class
*/
class ComicPanel extends JPanel {
public ComicPanel() {
this.add(new JLabel("Add your Comic components here"));
}
}
So it is your choice what you want to do. Possible is nearly everything ;)
Patrick
after looking for an answer for 3 hours, I am just about to give up on this idea:
I am making an application that displays the followers of a Twitch streamer.
A couple of features i am trying to add:
the display frame is a separate window from the controls frame.
I am trying to use (JFrame as display window) (JDialog as controls frame)
And furthermore: Settings is in another JDialog (this one has Modal(true))
Settings needs to be able to send the JFrame information such as: "username" and "text color"
And the settings JDialog will only pop up from clicking "settings" on the controls JDialog.
It will setVisible(false) when you click "save settings" or the X.
On the controls JDialog (b_console) needs to receive error messages and info like that.
And on the same JDialog, "filler" needs to receive follower count and things like that.
Here follows my code involving the transfers listed above:
package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics.*;
import javax.swing.*;
import java.io.*;
import java.net.URL;
public class JavaFollowerNotifier extends JFrame implements ComponentListener
{
Settings settings = new Settings();
ControlPanel ctrlPnl = new ControlPanel();
public JavaFollowerNotifier()
{
try
{
settings.readSettings();
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void grabFollower()
{
ctrlPnl.b_console.setText("Retrieving Info...");
try
{
URL twitch = new URL("https://api.twitch.tv/kraken/channels/" + savedSettings[1] + "/follows?limit=1&offset=0");
ctrlPnl.b_console.setText("Retrieved");
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void grabStats()
{
ctrlPnl.b_console.setText("Retrieving Info...");
try
{
URL twitch = new URL("https://api.twitch.tv/kraken/channels/" + savedSettings[1] + "/follows?limit=1&offset=0");
ctrlPnl.filler.setText("Followers: " + totalFollowers + "\nLatest: " + lastFollower);
ctrlPnl.b_console.setText("Retrieved");
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void componentMoved(ComponentEvent arg0)
{
//this is only to *attach this JDialog to the JFrame and make it move together my plan is to have it undecorated as well
int x = this.getX() + this.getWidth();
int y = this.getY();
ctrlPnl.movePanel(x, y);
}
public void paint(Graphics g)
{
if(clearPaint == false)
{
//any "savedSettings[n]" are saved in Settings.java (just not in this version)
g.setColor(Color.decode(savedSettings[3]));
scaledFont = scaleFont(follower + " followed!", bounds, g, new Font(savedSettings[2], Font.PLAIN, 200));
}
}
}
package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Settings extends JDialog implements ActionListener
{
JavaFollowerNotifier jfollow = new JavaFollowerNotifier();
ControlPanel ctrlPnl = new ControlPanel();
//here are the settings mention above
String[] savedSettings = {"imgs/b_b.jpg","username","font","color","Nightbot"};
public Settings()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void saveSettings()
{
savedSettings[4] = jfollow.lastFollower;
try
{
PrintWriter save = new PrintWriter("config.cfg");
ctrlPnl.b_console.setText("Saving...");
for(int i = 0; i < 5; i++)
{
save.println(savedSettings[i]);
}
save.close();
ctrlPnl.b_console.setText("Saved");
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
canClose = false;
}
readSettings();
this.repaint();
}
public void readSettings()
{
ctrlPnl.b_console.setText("Loading...");
try
{
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
jfollow.lastFollower = savedSettings[4];
try
{
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
ctrlPnl.b_console.setText("Loaded Settings");
}
}
package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ControlPanel extends JDialog implements ActionListener
{
public ControlPanel()
{
try
{
}
catch (Exception e)
{
b_console.setText("Error");
System.out.println(e);
}
}
public void movePanel(int x, int y)
{
//here is where i *attach the JDialog to the JFrame
controlPanel.setLocation(x, y);
}
public void actionPerformed(ActionEvent ie)
{
if(ie.getSource() == b_settings)
{
settings.frame.setVisible(true);
}
}
}
I tried to fix your program, but I wasn't too sure about its flow. So I created another simple one. What I did was pass the labels from the main frame to the dialogs' constructors. In the dialog, I took those labels and changed them with text entered in their text fields. If you hit enter after writing text from the dialog, you'll see the text in the frame change
public class JavaFollowerNotifier1 extends JFrame{
private JLabel controlDialogLabel = new JLabel(" ");
private JLabel settingDialogLabel = new JLabel(" ");
private ControlDialog control;
private SettingsDialog settings;
public JavaFollowerNotifier1() {
control = new ControlDialog(this, true, controlDialogLabel);
settings = new SettingsDialog(this, true, settingDialogLabel);
....
class ControlDialog extends JDialog {
private JLabel label;
public ControlDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
....
class SettingsDialog extends JDialog {
private JLabel label;
public SettingsDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
Test it out and let me know if you have any questions
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class JavaFollowerNotifier1 extends JFrame{
private JLabel controlDialogLabel = new JLabel(" ");
private JLabel settingDialogLabel = new JLabel(" ");
private JButton showControl = new JButton("Show Control");
private JButton showSetting = new JButton("Show Settings");
private ControlDialog control;
private SettingsDialog settings;
public JavaFollowerNotifier1() {
control = new ControlDialog(this, true, controlDialogLabel);
settings = new SettingsDialog(this, true, settingDialogLabel);
showControl.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
control.setVisible(true);
}
});
showSetting.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
settings.setVisible(true);
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(showControl);
buttonPanel.add(showSetting);
add(buttonPanel, BorderLayout.SOUTH);
add(controlDialogLabel, BorderLayout.NORTH);
add(settingDialogLabel, BorderLayout.CENTER);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JavaFollowerNotifier1();
}
});
}
}
class ControlDialog extends JDialog {
private JLabel label;
private JTextField field = new JTextField(15);
private JButton button = new JButton("Close");
private String s = "";
public ControlDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
setLayout(new BorderLayout());
add(field, BorderLayout.NORTH);
add(button, BorderLayout.CENTER);
pack();
setLocationRelativeTo(frame);
field.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
s = field.getText();
label.setText("Message from Control Dialog: " + s);
}
});
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
ControlDialog.this.setVisible(false);
}
});
}
}
class SettingsDialog extends JDialog {
private JLabel label;
private JTextField field = new JTextField(15);
private JButton button = new JButton("Close");
private String s = "";
public SettingsDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
setLayout(new BorderLayout());
add(field, BorderLayout.NORTH);
add(button, BorderLayout.CENTER);
pack();
setLocationRelativeTo(frame);
field.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
s = field.getText();
label.setText("Message from Settings Dialog: " + s);
}
});
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
SettingsDialog.this.setVisible(false);
}
});
}
}
Typically when I build GUI's which use modal dialogs to gather user input, I build my own class, which extends the JDialog or in some cases a JFrame. In that class I expose a getter method for an object which I usually call DialgResult. This object acts as the Model for the input I gather from the user. In the class that has the button, or whatever control which triggers asking the user for the information, I create it, show it as a modal dialog, then when it is closed, I retrieve the object using that same getter.
This is a very primitive example:
package arg;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class asdfas extends JFrame {
public static void main(String[] args) {
asdfas ex = new asdfas();
ex.setVisible(true);
}
public asdfas() {
init();
}
private void init() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setBounds(100,100,200,200);
final JButton button = new JButton("Show modal dialog");
button.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
Dialog d = new Dialog();
d.setVisible(true);
button.setText(d.getDialogResult().value);
revalidate();
repaint();
}
});
this.add(button);
}
class DialogResult {
public String value;
}
class Dialog extends JDialog {
JTextField tf = new JTextField(20);
private DialogResult result = new DialogResult();
public Dialog() {
super();
init();
}
private void init() {
this.setModal(true);
this.setSize(new Dimension(100,100));
JButton ok = new JButton("ok");
ok.addActionListener( new ActionListener () {
#Override
public void actionPerformed(ActionEvent arg0) {
result = new DialogResult();
result.value = tf.getText();
setVisible(false);
}
});
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
p.add(tf);
p.add(ok);
this.add(p);
}
public DialogResult getDialogResult() {
return result;
}
}
}
I am writing a program for a black jack game. It is an assignment we are not to use gui's but I am doing it for extra credit I have created two frames ant they are working. On the second frame I want to be able to switch back to the first when a button is pressed. How do I do this?
first window.............
import javax.swing.* ;
import java.awt.event.* ;
import java.awt.* ;
import java.util.* ;
public class BlackJackWindow1 extends JFrame implements ActionListener
{
private JButton play = new JButton("Play");
private JButton exit = new JButton("Exit");
private JPanel pane=new JPanel();
private JLabel lbl ;
public BlackJackWindow1()
{
super();
JPanel pane=new JPanel();
setTitle ("Black Jack!!!!!") ;
JFrame frame = new JFrame("");
setVisible(true);
setSize (380, 260) ;
setLocation (450, 200) ;
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE) ;
setLayout(new FlowLayout());
play = new JButton("Start");
exit = new JButton("exit");
lbl = new JLabel ("Welcome to Theodores Black Jack!!!!!");
add (lbl) ;
add(play, BorderLayout.CENTER);
play.addActionListener (this);
add(exit,BorderLayout.CENTER);
exit.addActionListener (this);
}
#Override
public void actionPerformed(ActionEvent event)
{
// TODO Auto-generated method stub
BlackJackWindow2 bl = new BlackJackWindow2();
if (event.getSource() == play)
{
bl.BlackJackWindow2();
}
else if(event.getSource() == exit){
System.exit(0);
}
}
second window....
import javax.swing.* ;
import java.awt.event.* ;
import java.awt.* ;
import java.util.* ;
public class BlackJackWindow2 extends JFrame implements ActionListener
{
private JButton hit ;
private JButton stay ;
private JButton back;
//private JLabel lbl;
public void BlackJackWindow2()
{
// TODO Auto-generated method stub
JPanel pane=new JPanel();
setTitle ("Black Jack!!!!!") ;
JFrame frame = new JFrame("");
setVisible(true);
setSize (380, 260) ;
setLocation (450, 200) ;
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE) ;
setLayout(new FlowLayout());
hit = new JButton("Hit");
stay = new JButton("stay");
back = new JButton("return to main menu");
// add (lbl) ;
add(hit, BorderLayout.CENTER);
hit.addActionListener (this) ;
add(stay,BorderLayout.CENTER);
stay.addActionListener (this) ;
add(back,BorderLayout.CENTER);
back.addActionListener (this) ;
}
#Override
public void actionPerformed(ActionEvent event)
{
// TODO Auto-generated method stub
BlackJackWindow1 bl = new BlackJackWindow1();
if (event.getSource() == hit)
{
//code for the game goes here i will complete later
}
else if(event.getSource() == stay){
//code for game goes here i will comeplete later.
}
else
{
//this is where i want the frame to close and go back to the original.
}
}
}
The second frame needs a reference to the first frame so that it can set the focus back to the first frame.
Also your classes extend JFrame but they are also creating other frames in their constructors.
A couple of suggestions:
You're adding components to a JPanel that uses FlowLayout but are using BorderLayout constants when doing this which you shouldn't do as it doesn't make sense:
add(play, BorderLayout.CENTER);
Rather, if using FlowLayout, just add the components without those constants.
Also, rather than swap JFrames, you might want to consider using a CardLayout and swapping veiws in a single JFrame. For instance:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FooBarBazDriver {
private static final String INTRO = "intro";
private static final String GAME = "game";
private CardLayout cardlayout = new CardLayout();
private JPanel mainPanel = new JPanel(cardlayout);
private IntroPanel introPanel = new IntroPanel();
private GamePanel gamePanel = new GamePanel();
public FooBarBazDriver() {
mainPanel.add(introPanel.getMainComponent(), INTRO);
mainPanel.add(gamePanel.getMainComponent(), GAME);
introPanel.addBazBtnActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardlayout.show(mainPanel, GAME);
}
});
gamePanel.addBackBtnActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardlayout.show(mainPanel, INTRO);
}
});
}
private JComponent getMainComponent() {
return mainPanel;
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Foo Bar Baz");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new FooBarBazDriver().getMainComponent());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class IntroPanel {
private JPanel mainPanel = new JPanel();
private JButton baz = new JButton("Baz");
private JButton exit = new JButton("Exit");
public IntroPanel() {
mainPanel.setLayout(new FlowLayout());
baz = new JButton("Start");
exit = new JButton("exit");
mainPanel.add(new JLabel("Hello World"));
mainPanel.add(baz);
mainPanel.add(exit);
exit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Window win = SwingUtilities.getWindowAncestor(mainPanel);
win.dispose();
}
});
}
public void addBazBtnActionListener(ActionListener listener) {
baz.addActionListener(listener);
}
public JComponent getMainComponent() {
return mainPanel;
}
}
class GamePanel {
private static final Dimension MAIN_SIZE = new Dimension(400, 200);
private JPanel mainPanel = new JPanel();
private JButton foo;
private JButton bar;
private JButton back;
public GamePanel() {
foo = new JButton("Foo");
bar = new JButton("Bar");
back = new JButton("return to main menu");
mainPanel.add(foo);
mainPanel.add(bar);
mainPanel.add(back);
mainPanel.setPreferredSize(MAIN_SIZE);
}
public JComponent getMainComponent() {
return mainPanel;
}
public void addBackBtnActionListener(ActionListener listener) {
back.addActionListener(listener);
}
}
Since I had to test it myself if it is in fact so easy to implement, I built this simple example. It demonstrates a solution to your problem. Slightly inspired by #jzd's answer (+1 for that).
import java.awt.Color;
import java.awt.HeadlessException;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class FocusChangeTwoFrames
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createGUI();
}
});
}
private static void createGUI() throws HeadlessException
{
final JFrame f2 = new JFrame();
f2.getContentPane().setBackground(Color.GREEN);
final JFrame f1 = new JFrame();
f1.getContentPane().setBackground(Color.RED);
f1.setSize(400, 300);
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setVisible(true);
MouseListener ml = new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e)
{
if(f1.hasFocus())
f2.requestFocus();
else
f1.requestFocus();
}
};
f1.addMouseListener(ml);
f2.setSize(400, 300);
f2.setLocation(200, 150);
f2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f2.setVisible(true);
f2.addMouseListener(ml);
}
}
Enjoy, Boro.