Hello while trying to build my Java GUI I keep running across the problem that my JPanels keep resizing or they just show up as small collapsed squares. I defined the size of each JPanel using the setSize() method.
This is what I'm getting
And this is more of what i'm trying to build
This is my code. I guess my question is how to stop the JPanels from resizing and sticking to their widths defined by the setSize() method.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import javaQuery.j2ee.GeoLocation;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class iPerf extends JFrame implements ActionListener{
private static final int JFrame_W = 437;
private static final int JFrame_H = 586;
private static final int titlePanel_W = 437;
private static final int titlePanel_H = 46;
private static final int locationPanel_W = 437;
private static final int locationPanel_H = 46;
private static final int buttonPanel_W = 437;
private static final int buttonPanel_H = 47;
private static final int resultsPanel_W = 437;
private static final int resultsPanel_H = 444;
private static final int outputPanel_W = 371;
private static final int outputPanel_H = 172;
JPanel titlePanel = new JPanel();
JPanel locationPanel = new JPanel();
JPanel buttonPanel = new JPanel();
JPanel resultsPanel = new JPanel();
JPanel pingResultsPanel = new JPanel();
JPanel iperfResultsPanel = new JPanel();
JLabel iperfTitle = new JLabel("iPerf");
JLabel cityTitleLabel = new JLabel("City");
JLabel cityResultLabel = new JLabel("");
JLabel countryTitleLabel = new JLabel("Country");
JLabel countryResultLabel = new JLabel("");
JLabel latitudeTitleLabel = new JLabel("Latitude");
JLabel latitudeResultLabel = new JLabel("");
JLabel longitudeTitleLabel = new JLabel("Longitude");
JLabel longitudeResultLabel = new JLabel("");
JScrollPane pingResultsScrollPane = new JScrollPane();
JScrollPane iPerfResultsScrollPane = new JScrollPane();
String results;
JTextArea label = new JTextArea(results);
JButton runButton = new JButton("Run iPerf");
public static void main(String[] args){
iPerf w = new iPerf( );
w.setVisible(true);
w.setResizable(false);
w.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
public iPerf() {
super();
setSize(JFrame_W, JFrame_H);
setTitle("iPerf");
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Title Panel
titlePanel.setSize(titlePanel_W, titlePanel_H);
titlePanel.setBackground(Color.darkGray);
titlePanel.add(iperfTitle);
add(titlePanel);
//Location Panel
locationPanel.setSize(locationPanel_W, locationPanel_H);
locationPanel.setBackground(Color.LIGHT_GRAY);
locationPanel.setLayout(new GridLayout(2, 4));
locationPanel.add(cityTitleLabel);
locationPanel.add(countryTitleLabel);
locationPanel.add(latitudeTitleLabel);
locationPanel.add(longitudeTitleLabel);
locationPanel.add(cityResultLabel);
locationPanel.add(countryResultLabel);
locationPanel.add(latitudeResultLabel);
locationPanel.add(longitudeResultLabel);
add(locationPanel);
//Button Panel
buttonPanel.setSize(buttonPanel_W, buttonPanel_H);
buttonPanel.setBackground(Color.LIGHT_GRAY);
buttonPanel.setLayout(new FlowLayout());
runButton.addActionListener(this);
buttonPanel.add(runButton);
add(buttonPanel);
//Results Panel
resultsPanel.setSize(resultsPanel_W, resultsPanel_H);
resultsPanel.setBackground(Color.darkGray);
resultsPanel.setLayout(new FlowLayout());
pingResultsPanel.setSize(outputPanel_W, outputPanel_H);
pingResultsPanel.setBackground(Color.WHITE);
pingResultsPanel.setLayout(new FlowLayout());
iperfResultsPanel.setSize(outputPanel_W, outputPanel_H);
iperfResultsPanel.setBackground(Color.WHITE);
iperfResultsPanel.setLayout(new FlowLayout());
iPerfResultsScrollPane.setViewportView(label);
iperfResultsPanel.add(iPerfResultsScrollPane);
resultsPanel.add(pingResultsPanel);
resultsPanel.add(iperfResultsPanel);
add(resultsPanel);
}
public void actionPerformed(ActionEvent e) {
String buttonString = e.getActionCommand();
if (buttonString.equals("Run iPerf")) {
System.out.println(buttonString + "it works!");
runIperfEastTCP iperfEastTCPThread = new runIperfEastTCP();
getLocation locationThread = new getLocation();
runPing pingThread = new runPing();
iperfEastTCPThread.start();
locationThread.start();
pingThread.start();
}
}
private class runPing extends Thread {
public void run() {
try {
String line;
Process p = Runtime.getRuntime().exec("/sbin/ping -c 4 www.google.com");
BufferedReader input = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
results += line + "\n";
label.setText(results);
System.out.println(line);
}
input.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class runIperfEastTCP extends Thread {
public void run() {
try {
String line = "";
Process p;
p = Runtime.getRuntime().exec("/usr/local/bin/iperf -c 184.72.222.65 -p 5001 -w 64k -P 4 -i 1 -t 10 -f k");
BufferedReader input = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
results += line + "\n";
label.setText(results);
System.out.println(line);
}
input.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class getLocation extends Thread {
public void run() {
try {
InetAddress thisIP = InetAddress.getLocalHost();
GeoLocation _gl = new GeoLocation();
_gl.GetGeoLocation(thisIP);
String IP = _gl.IP;
String Country = _gl.Country;
String City = _gl.City;
String Latitude = _gl.Latitude;
String Longitude = _gl.Longitude;
cityResultLabel.setText(City);
countryResultLabel.setText(Country);
latitudeResultLabel.setText(Latitude);
longitudeResultLabel.setText(Longitude);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Don't call setSize(...) on any component.
consider overriding getPreferredSize() if you absolutely need to set a size, but use it very sparingly.
You're not using layout managers correctly. Go through the layout manager tutorial as it will explain and show all that you need to know.
You need to call pack() on your JFrame after adding all components to it and before setting it visible or positioning it.
For example, you could...
Consider using BoxLayout for the overall structure
The top section could use a JLabel with the text centered.
The next section with the JLabels and JButton could use a BorderLayout
The BorderLayout could hold the JPanel that holds four labels/fields in the BorderLayout.CENTER position,
That same JPanel could use GridBagLayout.
the JPanel that holds the JButton could use a FlowLayout and be located in the BorderLayout.SOUTH or PAGE_END position of the BorderLayout-using JPanel.
Next JPanel can use a GridLayout with borders and gaps.
etc...
Try using another LayoutManager, like GridLayout.
Related
Im making an application that lets me perform hashes, at the top I want to have a group of check boxes basically saying the four different hash types I have. When the check boxes are selected I want the labels to appear showing the hashed entered text.
I've attached an image to hopefully make it easier to understand what I mean. The reason I'm doing this is so that when the final program is made with almost 10 rows of text boxes and labels it can be reduced only to show the ones that the user wishes to see.This hopefully should explain what I mean.
I've been able to get it so the checkboxes make it visible or not visible but that also then just leaves a blank space where one row of labels used to be rather than moving everything up a row
I've now added my coding so people can see how I'm doing it currently and help define where needs to be modified
import java.awt.*;
import java.awt.event.*;
import java.security.*;
import javax.swing.*;
public class Hasher extends JFrame implements ActionListener {
String UserInput;
private JTextField textInputField;
private static JLabel MD5Hashed,MD5Label;
private static JCheckBox MD5Check, SHA1Check, SHA256Check, FileCheck;
private JFrame contentPane;
public Hasher() {
this.setTitle("Hasher");
Container contentPane = this.getContentPane();
contentPane.setLayout(new GridLayout(0,1) );
contentPane.setBackground(new Color(88,148,202));
//CheckBoxes
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel checkBoxPanel = new JPanel();
MD5Check = new JCheckBox("MD5");
MD5Check.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
boolean Visible = MD5Check.isSelected();
MD5Hashed.setVisible(Visible);
MD5Label.setVisible(Visible);
}
});
checkBoxPanel.add(MD5Check);
SHA1Check = new JCheckBox("SHA-1");
checkBoxPanel.add(SHA1Check);
SHA256Check = new JCheckBox("SHA-256");
checkBoxPanel.add(SHA256Check);
FileCheck = new JCheckBox("File Hashing");
checkBoxPanel.add(FileCheck);
mainPanel.add(checkBoxPanel);
contentPane.add(mainPanel);
//Entered data to perform hash on
contentPane.add(new JLabel (" Enter text to hash"));
textInputField = new JTextField();
//HashingProcess inputListener = new HashingProcess( );
//textInputField.addActionListener(inputListener);
contentPane.add( textInputField);
//MD5 hash is completed
MD5Label = new JLabel( " Using MD5 the hash is: " );
contentPane.add( MD5Label);
MD5Hashed = new JLabel( "??") ;
contentPane.add( MD5Hashed );
MD5Hashed.setVisible(false);
MD5Label.setVisible(false);
}
public static void main(String[] args) {
Hasher theWindow = new Hasher( );
theWindow.setSize(400, 400 );
theWindow.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
theWindow.setVisible(true);
}
}
You have two frames...
public class Hasher extends JFrame implements ActionListener {
//...
private JFrame contentPane;
//..
This immediately raises the question, which one is actually on the screen and which one are you actually interacting with? While this might not be directly related to your problem, it is confusing.
As a general rule of thumb, don't extend from top level containers like JFrame, it locks you into a single use case and can cause no end of confusion. Instead, start with a JPanel and add it to an instance of JFrame or any other container you like.
The "main probable" problem is, Swing is lazy. It won't update the UI until you tell it or the UI is resized.
When adding and removing components, you need to call revalidate and repaint on the container to trigger an update - this is what's actually going wrong in your code, you're referencing contentPane, by that is private JFrame contentPane; and not the contentPane of the JFrame from which Hasher extends ... see, confusion.
Happening dug around your code a bit, it's obvious that you have a lot of repeated operations going on, the only core difference is the algorithm used to hash the text.
So, with that in mind, we can create some basic classes to do most of the work, for example...
public class HashPane extends JPanel {
private JLabel hashedLabel;
private JLabel promptLabel;
private HashAlgorithim algorithim;
public HashPane(String labelText, HashAlgorithim algorithim) {
setOpaque(false);
this.algorithim = algorithim;
setLayout(new FlowLayout(FlowLayout.LEFT));
promptLabel = new JLabel(labelText);
add(promptLabel);
hashedLabel = new JLabel("??");
add(hashedLabel);
}
public void setText(String text) {
hashedLabel.setText(algorithim.generateHash(text));
}
}
This is just two labels, which show a prompt and a result. The result is generated via a plug algorithm which is used to generate the hash for the supplied text
The algorithm itself is just a interface which defines the basic contract...
public interface HashAlgorithm {
public String generateHash(String from);
}
You would then need to create an implementation of each algorithm you wanted to use
Now, making a panel visible/invisible simply becomes a matter of associating a JCheckBox with a HashPane which can be achieved through a simple Map...
public class Hasher extends JPanel {
//...
private Map<JCheckBox, HashPane> mapPanes;
public Hasher() {
//...
HashPane md5Pane = new HashPane("MD5 hash = ", new NotAMD5Alorithim());
//...
HashPane sha1Pane = new HashPane("SHA-1 hash = ", new NotAMSHA1Alorithim());
//..
mapPanes = new HashMap<>(25);
mapPanes.put(MD5Check, md5Pane);
mapPanes.put(SHA1Check, sha1Pane);
//...
You can then use a single ActionListener to manage all the JCheckBoxs
public class Hasher extends JPanel {
//...
private Map<JCheckBox, HashPane> mapPanes;
public Hasher() {
//...
ActionHandler listener = new ActionHandler();
for (Entry<JCheckBox, HashPane> entry : mapPanes.entrySet()) {
entry.getKey().addActionListener(listener);
entry.getValue().setVisible(false);
}
}
protected class ActionHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JCheckBox cb = (JCheckBox) e.getSource();
HashPane hashPane = mapPanes.get(cb);
hashPane.setVisible(cb.isSelected());
revalidate();
repaint();
}
}
And because I pretty much butchered your code...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Hasher extends JPanel {
String UserInput;
private JTextField textInputField;
private static JCheckBox MD5Check, SHA1Check, SHA256Check, FileCheck;
private Map<JCheckBox, HashPane> mapPanes;
public Hasher() {
setLayout(new BorderLayout());
setBackground(new Color(88, 148, 202));
//CheckBoxes
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel checkBoxPanel = new JPanel();
MD5Check = new JCheckBox("MD5");
checkBoxPanel.add(MD5Check);
SHA1Check = new JCheckBox("SHA-1");
checkBoxPanel.add(SHA1Check);
SHA256Check = new JCheckBox("SHA-256");
checkBoxPanel.add(SHA256Check);
FileCheck = new JCheckBox("File Hashing");
checkBoxPanel.add(FileCheck);
mainPanel.add(checkBoxPanel);
add(mainPanel, BorderLayout.NORTH);
JPanel centerPane = new JPanel(new BorderLayout());
centerPane.setOpaque(false);
JPanel inputPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
inputPane.setOpaque(false);
//Entered data to perform hash on
inputPane.add(new JLabel("Enter text to hash: "));
textInputField = new JTextField(20);
inputPane.add(textInputField);
centerPane.add(inputPane, BorderLayout.NORTH);
JPanel output = new JPanel(new GridBagLayout());
output.setOpaque(false);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbc.gridwidth = GridBagConstraints.REMAINDER;
HashPane md5Pane = new HashPane("MD5 hash = ", new NotAMD5Alorithim());
output.add(md5Pane, gbc);
gbc.gridx = 0;
gbc.gridy++;
HashPane sha1Pane = new HashPane("SHA-1 hash = ", new NotAMSHA1Alorithim());
output.add(sha1Pane, gbc);
// last pane
gbc.gridy++;
gbc.weighty = 1;
output.add(new JLabel(), gbc);
centerPane.add(output);
add(centerPane);
mapPanes = new HashMap<>(25);
mapPanes.put(MD5Check, md5Pane);
mapPanes.put(SHA1Check, sha1Pane);
//...
ActionHandler listener = new ActionHandler();
for (Entry<JCheckBox, HashPane> entry : mapPanes.entrySet()) {
entry.getKey().addActionListener(listener);
entry.getValue().setVisible(false);
}
}
protected class ActionHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JCheckBox cb = (JCheckBox) e.getSource();
HashPane hashPane = mapPanes.get(cb);
hashPane.setVisible(cb.isSelected());
revalidate();
repaint();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Hasher());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface HashAlgorithm {
public String generateHash(String from);
}
public class NotAMD5Alorithim implements HashAlgorithm {
#Override
public String generateHash(String from) {
return "bananas";
}
}
public class NotAMSHA1Alorithim implements HashAlgorithm {
#Override
public String generateHash(String from) {
return "bananas";
}
}
public class HashPane extends JPanel {
private JLabel hashedLabel;
private JLabel promptLabel;
private HashAlgorithm algorithim;
public HashPane(String labelText, HashAlgorithm algorithim) {
setOpaque(false);
this.algorithim = algorithim;
setLayout(new FlowLayout(FlowLayout.LEFT));
promptLabel = new JLabel(labelText);
add(promptLabel);
hashedLabel = new JLabel("??");
add(hashedLabel);
}
public void setText(String text) {
hashedLabel.setText(algorithim.generateHash(text));
}
}
}
Having said all that, I might be tempted to have the JCheckBox in the HashPane and has the HashPane always visible and simply disable the output text ... or simply not bother and always have all the algorithms available all the time
you need to handle Events for all check-box while check/uncheck,
public void actionPerformed(ActionEvent actionEvent) {
if(all check-box un-checked){
// someLable.setVisible(false);
}else if(MD5 checked){
// peform operation based upon MD5
// someLable.setVisible(true);
}
// likewise for all others
}
Change
public void actionPerformed(ActionEvent e) {
boolean Visible = MD5Check.isSelected();
MD5Hashed.setVisible(Visible);
MD5Label.setVisible(Visible);
}
to:
public void actionPerformed(ActionEvent e) {
boolean Visible = MD5Check.isSelected();
MD5Hashed.setVisible(Visible);
MD5Label.setVisible(Visible);
contentPane.validate();
contentPane.repaint();
}
If You want to remove MD5Hashed and MD5Label then something like this:
{
if(MD5Check.isSelected()){
MD5Hashed.remove();
MD5Label.remove();
}
else{
contentPane.add( MD5Label);
contentPane.add( MD5Hashed );
}
contentPane.validate();
contentPane.repaint();
}
I am trying to make my program so that an integer value entered in a JTextfield can be stored into a variable. Then, when a JButton is clicked, this variable can tell a JSlider to move it's head to that of the integer value stored in the variable. My class name is Camera.Java
Code is showing no errors, however if I click my JButton, nothing happens, instead I see this error in the console:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:504)
at java.lang.Integer.parseInt(Integer.java:527)
at Camera.main(Camera.java:67)
My code:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Hashtable;
import java.util.Scanner;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JPanel;
import javax.swing.*;
public class Camera {
static JButton addtolist;
static Scanner input = new Scanner(System.in);
static JSlider cam = new JSlider();
static JTextField enterval = new JTextField();
static int x ;
public static void main (String args[]){
JFrame myFrame = new JFrame ("Matthew Damon on Mars");
myFrame.setSize(300, 600);
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
JLabel userinp = new JLabel("Enter input: ");
cam = new JSlider(0, 15, 0);
cam.setPaintLabels(true);
enterval.setPreferredSize(new Dimension(100,80));
addtolist = new JButton("Enter");
addtolist.setPreferredSize(new Dimension(50,20));
JTextField enterval1 = new JTextField();
panel.add(addtolist);
Hashtable<Integer, JLabel> table = new Hashtable<Integer, JLabel>();
table.put(0, new JLabel("0"));
table.put(1, new JLabel("1"));
table.put(2, new JLabel("2"));
table.put(3, new JLabel("3"));
table.put(4, new JLabel("4"));
table.put(5, new JLabel("5"));
table.put(6, new JLabel("6"));
table.put(7, new JLabel("7"));
table.put(8, new JLabel("8"));
table.put(9, new JLabel("9"));
table.put(10, new JLabel("A"));
table.put(11, new JLabel("B"));
table.put(12, new JLabel("C"));
table.put(13, new JLabel("D"));
table.put(14, new JLabel("E"));
table.put(15, new JLabel("F"));
cam.setLabelTable(table);
myFrame.add(cam, BorderLayout.SOUTH);
myFrame.add(userinp, BorderLayout.NORTH);
myFrame.add(enterval1, BorderLayout.NORTH);
myFrame.add(panel, BorderLayout.CENTER);
myFrame.setVisible(true);
buttonAction();
}
public static void buttonAction() {
addtolist.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
int x = Integer.parseInt(enterval.getText());
cam.setValue(x);
} catch (NumberFormatException npe) {
// show a warning message
}
}
});
}
}
Your setting x on program creation before the user has had any chance to change its value. Get the text value from within the actionPerformed method which should be after the user has already selected a value, parse it into a number and set the slider with that value.
public void actionPerformed(ActionEvent e) {
try {
int x = Integer.parseInt(enterval.getText());
cam.setValue(x);
} catch (NumberFormatException npe) {
// show a warning message
}
}
Then get rid of all that static nonsense. The only method that should be static here is main, and it should do nothing but create an instance and set it visible.
Note that better than using a JTextField, use a JSpinner or a JFormattedTextField or if you're really stuck, a DocumentFilter to limit what the user can enter
Again, you should put most everything into the instance realm and out of the static realm. This means getting most of that code outside of the main method and into other methods and constructors, that means not trying to access fields or methods from the class, but rather from the instance. For instance, your main method should only create the main instances, hook them up and set them running and that's it. It should not be used to build the specific GUI components. For example:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class CameraFoo extends JPanel {
// only static field here is a constant.
private static String TEXTS = "0123456789ABCDEF";
private JSpinner spinner = new JSpinner();
private JSlider slider = new JSlider(0, 15, 0);
public CameraFoo() {
List<Character> charList = new ArrayList<>();
Hashtable<Integer, JLabel> table = new Hashtable<>();
for (int i = 0; i < TEXTS.toCharArray().length; i++) {
char c = TEXTS.charAt(i);
String myText = String.valueOf(c);
JLabel label = new JLabel(myText);
table.put(i, label);
charList.add(c);
}
SpinnerListModel spinnerModel = new SpinnerListModel(charList);
spinner.setModel(spinnerModel);
slider.setLabelTable(table);
slider.setPaintLabels(true);
JPanel topPanel = new JPanel();
topPanel.add(spinner);
topPanel.add(new JButton(new ButtonAction("Press Me")));
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(slider);
}
private class ButtonAction extends AbstractAction {
public ButtonAction(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
char ch = (char) spinner.getValue();
int value = TEXTS.indexOf(ch);
slider.setValue(value);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
private static void createAndShowGui() {
CameraFoo mainPanel = new CameraFoo();
JFrame frame = new JFrame("CameraFoo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
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
I've searched through the forums but keep coming up empty for a solution.
I'm making a sort of library with a GUI program. What I want is for it to save entries via a text file. I can create objects fine with the methods I have, and can save them to a file easily. The problem comes from starting up the program again and populating a Vector with values in the text file. The objects I'm adding have a String value, followed by 7 booleans. When I try to load up from file, the String value is empty ("") and all booleans are false.
How do I get it to read the text before starting the rest of the GUI and filling the Vector right?
EDIT: Sorry for being very vague about it all. I'll post the code, but it's about 337 lines long..
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Scanner;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
#SuppressWarnings("serial")
public class SteamLibraryGUI extends JFrame implements ActionListener
{
//For main window
private JButton exitButton, addEntry, editEntry, removeEntry;
private JLabel selectGame, gameCount;
private JComboBox<String> gameCombo;
private Vector<Game> gamesList = new Vector<Game>();
private Vector<String> titleList = new Vector<String>();
private int numGames = gamesList.size();
private int selectedGame;
//For add window
private JFrame addFrame;
private JLabel gameTitle = new JLabel("Title:");
private JTextField titleText = new JTextField(60);
private JCheckBox singleBox, coopBox, multiBox, cloudBox, controllerBox, achieveBox, pcBox;
private JButton addGame, addCancel;
//For edit window
private JFrame editFrame;
private JButton editGame, editCancel;
public SteamLibraryGUI()
{
setTitle("Steam Library Organizer");
addEntry = new JButton("Add a game");
editEntry = new JButton("Edit a game");
removeEntry = new JButton("Remove a game");
exitButton = new JButton("Exit");
selectGame = new JLabel("Select a game:");
gameCount = new JLabel("Number of games:"+numGames);
gameCombo = new JComboBox<String>(titleList);
JPanel selectPanel = new JPanel();
selectPanel.setLayout(new GridLayout(1,2));
selectPanel.add(selectGame);
selectPanel.add(gameCombo);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1,3));
buttonPanel.add(addEntry);
buttonPanel.add(editEntry);
buttonPanel.add(removeEntry);
JPanel exitPanel = new JPanel();
exitPanel.setLayout(new GridLayout(1,2));
exitPanel.add(gameCount);
exitPanel.add(exitButton);
Container pane = getContentPane();
pane.setLayout(new GridLayout(3,1));
pane.add(selectPanel);
pane.add(buttonPanel);
pane.add(exitPanel);
addEntry.addActionListener(this);
editEntry.addActionListener(this);
removeEntry.addActionListener(this);
exitButton.addActionListener(this);
gameCombo.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==addEntry)
addEntry();
if(e.getSource()==editEntry)
editEntry(gamesList.get(selectedGame));
if(e.getSource()==removeEntry)
{
removeEntry(selectedGame);
update();
}
if(e.getSource()==exitButton)
exitProg();
if(e.getSource()==gameCombo)
{
selectedGame = gameCombo.getSelectedIndex();
}
if(e.getSource()==singleBox)
singleBox.isSelected();
if(e.getSource()==coopBox)
coopBox.isSelected();
if(e.getSource()==multiBox)
multiBox.isSelected();
if(e.getSource()==cloudBox)
cloudBox.isSelected();
if(e.getSource()==controllerBox)
controllerBox.isSelected();
if(e.getSource()==achieveBox)
achieveBox.isSelected();
if(e.getSource()==pcBox)
pcBox.isSelected();
if(e.getSource()==addGame)
{
gamesList.add(new Game(titleText.getText(), singleBox.isSelected(), coopBox.isSelected(),
multiBox.isSelected(), cloudBox.isSelected(), controllerBox.isSelected(),
achieveBox.isSelected(), pcBox.isSelected()));
titleList.add(titleText.getText());
addFrame.dispose();
update();
}
if(e.getSource()==addCancel)
addFrame.dispose();
if(e.getSource()==editCancel)
editFrame.dispose();
if(e.getSource()==editGame)
{
gamesList.get(selectedGame).name = titleText.getText();
gamesList.get(selectedGame).single = singleBox.isSelected();
gamesList.get(selectedGame).coop = coopBox.isSelected();
gamesList.get(selectedGame).multi = multiBox.isSelected();
gamesList.get(selectedGame).cloud = cloudBox.isSelected();
gamesList.get(selectedGame).controller = controllerBox.isSelected();
gamesList.get(selectedGame).achieve = achieveBox.isSelected();
gamesList.get(selectedGame).pc = pcBox.isSelected();
titleList.remove(selectedGame);
titleList.add(titleText.getText());
editFrame.dispose();
update();
}
}
public void update()
{
Collections.sort(titleList);
Collections.sort(gamesList);
gameCombo.updateUI();
titleText.setText("");
gameCombo.setSelectedIndex(-1);
numGames = gamesList.size();
gameCount.setText("Number of games:"+numGames);
}
public void addEntry()
{
addFrame = new JFrame("Add Entry");
addFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
addFrame.getContentPane();
addFrame.setLayout(new GridLayout(3,1));
singleBox = new JCheckBox("Single-Player");
singleBox.setSelected(false);
coopBox = new JCheckBox("Coop");
coopBox.setSelected(false);
multiBox = new JCheckBox("MultiPlayer");
multiBox.setSelected(false);
cloudBox = new JCheckBox("Steam Cloud");
cloudBox.setSelected(false);
controllerBox = new JCheckBox("Controller Support");
controllerBox.setSelected(false);
achieveBox = new JCheckBox("Achievements");
achieveBox.setSelected(false);
pcBox = new JCheckBox("For New PC");
pcBox.setSelected(false);
addGame = new JButton("Add game");
addCancel = new JButton("Cancel");
JPanel titlePanel = new JPanel();
titlePanel.setLayout(new FlowLayout());
titlePanel.add(gameTitle);
titlePanel.add(titleText);
JPanel checkPanel = new JPanel();
checkPanel.setLayout(new FlowLayout());
checkPanel.add(singleBox);
checkPanel.add(coopBox);
checkPanel.add(multiBox);
checkPanel.add(cloudBox);
checkPanel.add(controllerBox);
checkPanel.add(achieveBox);
checkPanel.add(pcBox);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.add(addGame);
buttonPanel.add(addCancel);
addFrame.add(titlePanel);
addFrame.add(checkPanel);
addFrame.add(buttonPanel);
singleBox.addActionListener(this);
coopBox.addActionListener(this);
multiBox.addActionListener(this);
cloudBox.addActionListener(this);
controllerBox.addActionListener(this);
achieveBox.addActionListener(this);
pcBox.addActionListener(this);
addGame.addActionListener(this);
addCancel.addActionListener(this);
addFrame.pack();
addFrame.setVisible(true);
}
public void editEntry(Game g)
{
editFrame = new JFrame("Edit Entry");
editFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
editFrame.getContentPane();
editFrame.setLayout(new GridLayout(3,1));
singleBox = new JCheckBox("Single-Player");
singleBox.setSelected(g.single);
coopBox = new JCheckBox("Coop");
coopBox.setSelected(g.coop);
multiBox = new JCheckBox("MultiPlayer");
multiBox.setSelected(g.multi);
cloudBox = new JCheckBox("Steam Cloud");
cloudBox.setSelected(g.cloud);
controllerBox = new JCheckBox("Controller Support");
controllerBox.setSelected(g.controller);
achieveBox = new JCheckBox("Achievements");
achieveBox.setSelected(g.achieve);
pcBox = new JCheckBox("For New PC");
pcBox.setSelected(g.pc);
editGame = new JButton("Edit game");
editCancel = new JButton("Cancel");
titleText.setText(g.name);
JPanel titlePanel = new JPanel();
titlePanel.setLayout(new FlowLayout());
titlePanel.add(gameTitle);
titlePanel.add(titleText);
JPanel checkPanel = new JPanel();
checkPanel.setLayout(new FlowLayout());
checkPanel.add(singleBox);
checkPanel.add(coopBox);
checkPanel.add(multiBox);
checkPanel.add(cloudBox);
checkPanel.add(controllerBox);
checkPanel.add(achieveBox);
checkPanel.add(pcBox);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.add(editGame);
buttonPanel.add(editCancel);
editFrame.add(titlePanel);
editFrame.add(checkPanel);
editFrame.add(buttonPanel);
singleBox.addActionListener(this);
coopBox.addActionListener(this);
multiBox.addActionListener(this);
cloudBox.addActionListener(this);
controllerBox.addActionListener(this);
achieveBox.addActionListener(this);
pcBox.addActionListener(this);
editGame.addActionListener(this);
editCancel.addActionListener(this);
editFrame.pack();
editFrame.setVisible(true);
}
public void removeEntry(int g)
{
Object[] options = {"Yes, remove the game", "No, keep the game"};
int n = JOptionPane.showOptionDialog(null, "Are you sure you want to remove this game from the list?",
"Remove game?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[1]);
if (n==0)
{
gamesList.remove(g);
titleList.remove(g);
}
}
public void exitProg()
{
try
{
PrintWriter out = new PrintWriter("games.txt");
out.flush();
for(int i=0;i<gamesList.size();i++)
{
out.print(gamesList.get(i).toString());
}
out.close();
}
catch (FileNotFoundException e) {}
System.exit(0);
}
public static void main(String[] args)
{
SteamLibraryGUI frame = new SteamLibraryGUI();
frame.pack();
frame.setSize(600,200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Scanner in = new Scanner("games.txt");
while(in.hasNextLine())
{
String line = in.nextLine();
String[] options = line.split("|");
Game g = new Game(options[0],Boolean.getBoolean(options[1]),
Boolean.getBoolean(options[2]),Boolean.getBoolean(options[3]),
Boolean.getBoolean(options[4]),Boolean.getBoolean(options[5]),
Boolean.getBoolean(options[6]),Boolean.getBoolean(options[7]));
frame.gamesList.add(g);
frame.titleList.add(options[0]);
System.out.println(g.toString());
}
in.close();
}
}
There's also a Game class, but it's simply 1 String, and then 7 booleans.
There were two significant bugs in the code. First, Scanner was constructed with a string parameter (which means that the Scanner scanned the string, not the file named by the string). Second, the pipe character "|" is a regular expression metacharacter. That is important because line.split() splits on regular expressions. Thus, the "|" has to be escaped. The main() function works fine if it is written as follows (with debugging output code included to show that each step is working correctly):
public static void main(String[] args)
{
SteamLibraryGUI frame = new SteamLibraryGUI();
frame.pack();
frame.setSize(600,200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try
{
Scanner in = new Scanner(new File("games.txt"));
while(in.hasNextLine())
{
System.out.println("line = ");
String line = in.nextLine();
System.out.println(line);
String[] options = line.split("\\|");
System.out.println("Options = ");
for (String s : options)
{
System.out.println(s);
}
Game g = new Game(options[0],Boolean.getBoolean(options[1]),
Boolean.getBoolean(options[2]),Boolean.getBoolean(options[3]),
Boolean.getBoolean(options[4]),Boolean.getBoolean(options[5]),
Boolean.getBoolean(options[6]),Boolean.getBoolean(options[7]));
frame.gamesList.add(g);
frame.titleList.add(options[0]);
System.out.println(g.toString());
}
in.close();
} catch (IOException x)
{
System.err.println(x);
}
}
There is one other important Gotcha: The method exitProg() writes the "games.txt" file out again before the program finishes. This creates a problem if the file was read incorrectly in the first place because the wrong data will be written back to the file. During testing, this means that even when the reading code has been corrected, it will still read the erroneous data that was written from a previous test run.
My preference in this situation is would be to isolate all the reading and writing code for "game.txt" inside the Game class (which makes it easier to verify that the reading and writing formats are identical) and only write the code to write the data back out once I'd written and tested the reading code, which would avoid this Gotcha.