I'm trying to write a piece of code that when I check one of the two checkboxes, it will change the message that appears when I then select the button.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class FirstWindow extends JFrame{
String message;
public static void main(String[] args){
//the string to show the message for button 1
message = "goodjob \n";
//all of the main window
JFrame frame = new JFrame("heading");
frame.setVisible(true);
frame.setSize(600,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
//makes seperate panels
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JPanel panel3 = new JPanel(new GridBagLayout());
//set of buttons
JButton button1 = new JButton("Button 1");
JButton button2 = new JButton("Button 2");
//makes an ACTION LISTENER, which tells the button what to do when
//it is pressed.
button1.addActionListener(new ActionListener(){
//the command to button
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, message);
}
});
//for panel adds buttons
panel1.add(button1);
panel1.add(button2);
//set of checkboxes
JCheckBox checkBox = new JCheckBox("Option1");
JCheckBox checkBox2 = new JCheckBox("Option2");
//adds text if the box is checked
if (checkBox.isSelected())
{
message += "you picked option 1";
}
if (checkBox2.isSelected())
{
message += "you picked option 2";
}
//for panel2 adds checkboxes
panel2.add(checkBox);
panel2.add(checkBox2);
//makes a new label, text area and field
JLabel label = new JLabel("This is a label");
JTextArea textArea = new JTextArea("this is a text area");
JTextField textField = new JTextField("text field");
//makes an invisible grid
GridBagConstraints grid = new GridBagConstraints();
grid.insets = new Insets(15, 15, 15, 15);
//sets the the coordinates 0,0. adds the label, and sets position
grid.gridx = 0;
grid.gridy = 0;
panel3.add(label, grid);
//sets the the coordinates 0,1. adds the textArea, and sets position
grid.gridx = 0;
grid.gridy = 1;
panel3.add(textArea, grid);
//sets the the coordinates 0,2. adds the text field, and sets position
grid.gridx = 0;
grid.gridy = 2;
panel3.add(textField, grid);
//adds each PANEL to the FRAME and positions it
frame.add(panel1, BorderLayout.SOUTH);
frame.add(panel3, BorderLayout.CENTER);
frame.add(panel2, BorderLayout.NORTH);
}
}
The error message I'm receiving is:
"FirstWindow.java:12: error: non-static variable message cannot be referenced from a static context
message = "goodjob \n";"
for lines 12, 37, 53, 57. I've tried declaring the String variable in the main but then I will just receive the error:
"FirstWindow.java:38: error: local variables referenced from an inner class must be final or effectively final JOptionPane.showMessageDialog(null, message);"
How to solve this problem?
Make the message field static:
static String message;
Your main class is static (as it has to be). This means you don't have an instance of your class. But the field message is currently not static, this means it only exists as part of an instance. Since you don't have an instance you can't access it.
As a side note: I strongly suggest you get someone to code review this code. There is a lot to learn. Consider submitting it to Code Review.
The problem here is, you declared non-static variable String message outside of public static void main() which is a static method.
So there are three possible solutions
Declare string message inside the main method
public static void main(String []args){
String message = "goodjob \n";
Based on the answers above, you can change String message to static
static String message;
public static void main(String []args){
message = "goodjob \n";
Create an object of class FirstWindow and then access the String message
FirstWindow sampleFirst = new FirstWindow();
sampleFirst.message = "goodjob \n";
I recommend you to create a constructor and avoid the use of static variable in this case:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class FirstWindow extends JFrame{
private String message;
FirstWindow (){
super("heading");
//the string to show the message for button 1
message = "goodjob \n";
//all of the main window
// remove this: JFrame frame = new JFrame("heading");
// remove this: frame.setVisible(true);
// change frame.setSize(600,400); by:
setSize(600,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// the rest of your code with the JFrame instantiation
// ...
//adds each PANEL to the FRAME and positions it
// here also change frame.add(... by just add(... as follows
add(panel1, BorderLayout.SOUTH);
add(panel3, BorderLayout.CENTER);
add(panel2, BorderLayout.NORTH);
}
public static void main(String[] args){
new FirstWindow().setVisible(true);
}
}
Related
Hi I'm working on a program and I faced a problem when I choose some settings from JDialog then click "ok", which is that the setting didn't save but come back to the original settings.
PS : I'm not English speaker so maybe you observe some mistakes in my text above.
picture
enter image description here
class DrawingSettingWindow extends JDialog {
public DrawingSettingWindow() {
this.setTitle("Drawing Setting Window");
this.setSize(550, 550);
this.setLocationRelativeTo(null);
this.setModal(true);
this.setLayout(new GridLayout(4, 1));
JLabel selectColorText = new JLabel("Select Drawing Color");
colorsList = new JComboBox(colors);
JPanel panel1 = new JPanel();
panel1.add(selectColorText);
panel1.add(colorsList);
add(panel1);
JLabel selectStyleText = new JLabel("Select Drawing Style");
JPanel panel2 = new JPanel();
normal = new JRadioButton("Normal");
normal.setSelected(true);
filled = new JRadioButton("Filled");
ButtonGroup bg = new ButtonGroup();
bg.add(normal);
bg.add(filled);
panel2.add(selectStyleText);
panel2.add(normal);
panel2.add(filled);
add(panel2);
JButton ok = new JButton("OK");
add(ok);
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
this.pack();
this.setVisible(true);
}
The information is there, you just have to extract it from the dialog after the user is done using it. I would give the code above at least two new methods, one a public getColor() method that returns colorsList.getSelectedItem();, the color selection of the user (I'm not sure what type of object this is, so I can't show the method yet). Also another one that gets the user's filled setting, perhaps
public boolean getFilled() {
return filled.isSelected();
}
Since the dialog is modal, you'll know that the user has finished using it immediately after you set it visible in the calling code. And this is where you call the above methods to extract the data.
In the code below, I've shown this in this section: drawingSettings.setVisible(true);
// here you extract the data
Object color = drawingSettings.getColor();
boolean filled = drawingSettings.getFilled();
textArea.append("Color: " + color + "\n");
textArea.append("Filled: " + filled + "\n");
}
For example (see comments):
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
#SuppressWarnings("serial")
public class UseDrawingSettings extends JPanel {
private JTextArea textArea = new JTextArea(20, 40);
private DrawingSettingWindow drawingSettings;
public UseDrawingSettings() {
JPanel topPanel = new JPanel();
topPanel.add(new JButton(new ShowDrawSettings()));
setLayout(new BorderLayout());
add(new JScrollPane(textArea));
add(topPanel, BorderLayout.PAGE_START);
}
private class ShowDrawSettings extends AbstractAction {
public ShowDrawSettings() {
super("Get Drawing Settings");
}
#Override
public void actionPerformed(ActionEvent e) {
if (drawingSettings == null) {
Window win = SwingUtilities.getWindowAncestor(UseDrawingSettings.this);
drawingSettings = new DrawingSettingWindow(win);
}
drawingSettings.setVisible(true);
// here you extract the data
Object color = drawingSettings.getColor();
boolean filled = drawingSettings.getFilled();
textArea.append("Color: " + color + "\n");
textArea.append("Filled: " + filled + "\n");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
UseDrawingSettings mainPanel = new UseDrawingSettings();
JFrame frame = new JFrame("UseDrawingSettings");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
#SuppressWarnings("serial")
class DrawingSettingWindow extends JDialog {
private static final String TITLE = "Drawing Setting Window";
private JComboBox<String> colorsList;
private JRadioButton normal;
private JRadioButton filled;
// not sure what colors is, but I'll make it a String array for testing
private String[] colors = {"Red", "Orange", "Yellow", "Green", "Blue"};
public DrawingSettingWindow(Window win) {
super(win, TITLE, ModalityType.APPLICATION_MODAL);
// this.setTitle("Drawing Setting Window");
this.setSize(550, 550); // !! this is not recommended
this.setLocationRelativeTo(null);
this.setModal(true);
this.setLayout(new GridLayout(4, 1));
JLabel selectColorText = new JLabel("Select Drawing Color");
colorsList = new JComboBox(colors);
JPanel panel1 = new JPanel();
panel1.add(selectColorText);
panel1.add(colorsList);
add(panel1);
JLabel selectStyleText = new JLabel("Select Drawing Style");
JPanel panel2 = new JPanel();
normal = new JRadioButton("Normal");
normal.setSelected(true);
filled = new JRadioButton("Filled");
ButtonGroup bg = new ButtonGroup();
bg.add(normal);
bg.add(filled);
panel2.add(selectStyleText);
panel2.add(normal);
panel2.add(filled);
add(panel2);
JButton ok = new JButton("OK");
add(ok);
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
this.pack();
// this.setVisible(true); // this should be the calling code's responsibility
}
public Object getColor() {
return colorsList.getSelectedItem();
}
public boolean getFilled() {
return filled.isSelected();
}
public static void main(String[] args) {
JFrame frame = new JFrame("Foo");
}
}
Side notes:
I've changed your class's constructor to accept a Window parameter, the base class for JFrame, JDialog, and such, and have added a call to the super's constructor. This way, the dialog is a true child window of the calling code (or you can pass in null if you want it not to be).
I recommend not making the dialog visible within its constructor. It is the calling code's responsibility for doing this, and there are instances where the calling code will wish to not make the dialog visible after creating it, for example if it wanted to attach a PropertyChangeListener to it before making it visible. This is most important for modal dialogs, but is just good programming practice.
I didn't know the type of objects held by your combo box, and so made an array of String for demonstration purposes.
I've been working on creating a simple GUI through the use of JPanels. I've managed to what I believe fluke a reasonably looking layout and now I would like the user to be able to input values into the Mass textbox and the Acceleration textbox so when they hit calculate they are given a message telling them the Force.
The issue I am having is within the public void that is added to the buttons, I can't seem to figure out how to refer to values within the text field. I've tried to just refer to it generally by:
String mass = txts[1].getText();
However this doesn't recognise txts as existing?
Any help on this would be much appreciated.
Below is the full code in case it helps.
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.event.*;
import java.awt.*;
public class InitScreen {
public static void createHomeScreen() {
/*Creates a Java Frame with the Window Name = HomeScreen*/
JFrame frame = new JFrame("HomeScreen");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,400);
frame.getContentPane().setPreferredSize(new Dimension(400,300));
frame.pack();
/*Creates the main JPanel in form of GridLayout*/
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
mainPanel.setBorder(new EmptyBorder(new Insets(20,20,20,20)));
/*Creates the first sub panel*/
JPanel firstPanel = new JPanel();
firstPanel.setLayout(new GridLayout(1,2,75,100));
firstPanel.setMaximumSize(new Dimension(300,100));
/*Creates the buttons in the first sub panel*/
JButton[] btns = new JButton[2];
String bText[] = {"Calculate", "Clear"};
for (int i=0; i<2; i++) {
btns[i] = new JButton(bText[i]);
btns[i].setPreferredSize(new Dimension(100, 50));
btns[i].setActionCommand(bText[i]);
btns[i].addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
String choice = e.getActionCommand();
/*JOptionPane.showMessageDialog(null, "Clicked "+choice);*/
JOptionPane.showMessageDialog(null, "Force = ");
}
});
firstPanel.add(btns[i]);
}
/*Creates the second sub panel*/
JPanel secondPanel = new JPanel();
secondPanel.setLayout(new BorderLayout());
/*Creates the labels for the second sub panel*/
JLabel label = new JLabel("Calculate the Force of an Object", SwingConstants.CENTER);
secondPanel.add(label,BorderLayout.NORTH);
/*Creates the third sub Panel for entering values*/
JPanel thirdPanel = new JPanel();
thirdPanel.setLayout(new GridLayout(3,1,10,10));
thirdPanel.setMaximumSize(new Dimension(400,100));
/*Create labels and text fields for third sub panel*/
String lText[] = {"Mass of Body", "Acceleration of Body", "Force"};
JLabel[] lbls = new JLabel[3];
JTextField[] txts = new JTextField[3];
for (int i=0; i<3; i++) {
txts[i] = new JTextField();
lbls[i] = new JLabel(lText[i], SwingConstants.LEFT);
lbls[i].setPreferredSize(new Dimension(50, 50));
thirdPanel.add(lbls[i]);
thirdPanel.add(txts[i]);
}
mainPanel.add(secondPanel);
mainPanel.add(thirdPanel);
mainPanel.add(firstPanel);
frame.setContentPane(mainPanel);
frame.setVisible(true);
}
public static void main(final String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createHomeScreen();
}
});
}
}
First drop the reliance on static, and instead, create an instance of InitScreen and call it's createHomeScreen method
public class InitScreen {
public void createHomeScreen() {
//...
}
public static void main(final String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
InitScreen screen = new InitScreen();
screen.createHomeScreen();
}
});
}
Now, make txts and instance field of InitScreen and use it within your methods
public class InitScreen {
private JTextField[] txts;
public void createHomeScreen() {
//...
txts = new JTextField[3];
//...
}
This takes txts from a local context to a class instance context, meaning you can now access it from any method within InitScreen
I'm new to programming with Java.
I have these two small projects.
import javax.swing.*;
public class tutorial {
public static void main(String[] args){
JFrame frame = new JFrame("Test");
frame.setVisible(true);
frame.setSize(300,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("hello");
JPanel panel = new JPanel();
frame.add(panel);
panel.add(label);
JButton button = new JButton("Hello again");
panel.add(button);
}
}
and this one:
import java.util.*;
public class Test {
public static void main(String[] args){
int age;
Scanner keyboard = new Scanner(System.in);
System.out.println("How old are you?");
age = keyboard.nextInt();
if (age<18)
{
System.out.println("Hi youngster!");
}
else
{
System.out.println("Hello mature!");
}
}
}
How can I add the second code to the first one, so that the user will see a window that says 'How old are you' and they can type their age.
Thanks in advance!
I'm not sure of all the things you wanted because it was undefined, but as I far as I understand, you wanted a JFrame containing an input field, in which you will be able to input values and display the appropriate answer.
I also suggest you read tutorial , but don't hesitate if you have question.
I hope it's a bit close to what you wanted.
package example.tutorial;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Tutorial extends JPanel {
private static final String YOUNG_RESPONSE = "Hi youngster!";
private static final String ADULT_RESPONSE = "Hello mature!";
private static final String INVALID_AGE = "Invalid age!";
private static final int MIN_AGE = 0;
private static final int MAX_AGE = 100;
private static JTextField ageField;
private static JLabel res;
private Tutorial() {
setLayout(new BorderLayout());
JPanel northPanel = new JPanel();
northPanel.setLayout(new FlowLayout());
JLabel label = new JLabel("How old are you ? ");
northPanel.add(label);
ageField = new JTextField(15);
northPanel.add(ageField);
add(northPanel, BorderLayout.NORTH);
JPanel centerPanel = new JPanel();
JButton btn = new JButton("Hello again");
btn.addActionListener(new BtnListener());
centerPanel.add(btn);
res = new JLabel();
res.setVisible(false);
centerPanel.add(res);
add(centerPanel, BorderLayout.CENTER);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.add(new Tutorial());
frame.setVisible(true);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private static class BtnListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
String content = ageField.getText();
int age = -1;
try{
age = Integer.parseInt(content);
if(isValid(age)) {
res.setText(age < 18 ? YOUNG_RESPONSE : ADULT_RESPONSE);
} else {
res.setText(INVALID_AGE);
}
if(!res.isVisible())
res.setVisible(true);
} catch(NumberFormatException ex) {
res.setText("Wrong input");
}
}
private boolean isValid(int age) {
return age > MIN_AGE && age < MAX_AGE;
}
}
}
so that the user will see a window that says 'How old are you' and they can type their age.
The easiest way to start would be to use a JOptionPane. Check out the section from the Swing tutorial on How to Use Dialogs for examples and explanation.
Don't forget to look at the table of contents for other Swing related topics for basic information about Swing.
You will need an input field to get the text and then add an ActionListener to the button which contains the logic that is performed when the button is pressed.
I modified your code to implement what you described:
import javax.swing.*;
import java.awt.event.*;
public class tutorial {
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setVisible(true);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("hello");
JPanel panel = new JPanel();
frame.add(panel);
panel.add(label);
final JTextField input = new JTextField(5); // The input field with a width of 5 columns
panel.add(input);
JButton button = new JButton("Hello again");
panel.add(button);
final JLabel output = new JLabel(); // A label for your output
panel.add(output);
button.addActionListener(new ActionListener() { // The action listener which notices when the button is pressed
public void actionPerformed(ActionEvent e) {
String inputText = input.getText();
int age = Integer.parseInt(inputText);
if (age < 18) {
output.setText("Hi youngster!");
} else {
output.setText("Hello mature!");
}
}
});
}
}
In that example we don't validate the input. So if the input is not an Integer Integer.parseInt will throw an exception. Also the components are not arranged nicely. But to keep it simple for the start that should do it. :)
it's not an easy question since you are working on command line in one example, and in a Swing GUI in the other.
Here's a working example, i've commented here and there.
This is no where near java best practises and it misses a lot of validation (just see what happens when you enter a few letters or nothing in the textfield.
Also please ignore the setLayout(null) and setBounds() statements, it's just a simple example not using any layout managers.
I hope my comments will help you discovering java!
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
//You'll need to implement the ActionListener to listen to buttonclicks
public class Age implements ActionListener{
//Declare class variables so you can use them in different functions
JLabel label;
JTextField textfield;
//Don't do al your code in the static main function, instead create an instance
public static void main(String[] args){
new Age();
}
// this constructor is called when you create a new Age(); like in the main function above.
public Age()
{
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300,300);
frame.setLayout(null);
JPanel panel = new JPanel();
panel.setBounds(0,0,300,300);
panel.setLayout(null);
label = new JLabel("hello");
label.setBounds(5,5,100,20);
// a JTextfield allows the user to edit the text in the field.
textfield = new JTextField();
textfield.setBounds(5,30,100,20);
JButton button = new JButton("Hello again");
button.setBounds(130,30,100,20);
// Add this instance as the actionlistener, when the button is clicked, function actionPerformed will be called.
button.addActionListener(this);
panel.add(label);
panel.add(textfield);
panel.add(button);
frame.add(panel);
frame.setVisible(true);
}
//Required function actionPerformed for ActionListener. When the button is clicked, this function is called.
#Override
public void actionPerformed(ActionEvent e)
{
// get the text from the input.
String text = textfield.getText();
// parse the integer value from the string (! needs validation for wrong inputs !)
int age = Integer.parseInt(text);
if (age<18)
{
//instead of writing out, update the text of the label.
label.setText("Hi youngster!");
}
else
{
label.setText("Hello mature!");
}
}
}
I'm working on a calculator/phone input keypad, and am having all sorts of trouble getting it to actually display the buttons. I got it to work when everything was in the main method, but that wouldn't allow me to implement ActionListener, which I need in order for the buttons to work. Here's the code I have right now:
import java.awt.*; //Import everything
import java.util.*;
import java.awt.event.*;
import javax.swing.*; //Seriously, everything, just makes this easier
public class Keypad extends JPanel implements ActionListener {
public static void main(String[] args) {
//Create the frame that holds everything else
JFrame frame = new JFrame ("Almost Functional Keypad");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
//Create the keypad
frame.getContentPane().add(new Keypad());
//Stuff to do so it won't break
frame.setPreferredSize(new Dimension(350,400));
frame.pack();
frame.setVisible(true);
frame.setResizable(false);
}
public Keypad(){
//Create the array of JPanels and labels
JButton[] keyList = new JButton[12];
JLabel[] keyLabel = new JLabel[12];
//Array with the key labels
String[] keyLabelText = {"1","2","3","4","5","6","7","8","9","*","0","#"};
//We need a counter
int i;
//Create the panels
for (i=0; i<12; i++){
keyList[i]= new JButton();
keyList[i].setPreferredSize (new Dimension(100, 75));
keyLabel[i] = new JLabel (keyLabelText[i]);
keyList[i].add (keyLabel[i]);
keyList[i].addActionListener(this);
}
//Text field that only the buttons can modify
JTextArea displayText = new JTextArea();
displayText.setPreferredSize(new Dimension(320, 20));
//Create the "clear" button
JButton clear = new JButton();
clear.setPreferredSize(new Dimension(300, 40));
JLabel clearLabel = new JLabel ("Clear");
clear.add(clearLabel);
clear.addActionListener(this);
// Set up primary panel
JPanel primary = new JPanel();
primary.add(displayText);
for (i=0; i<12; i++){
primary.add (keyList[i]);
}
primary.add(clear);
}
public void actionPerformed (ActionEvent event){
//Stuff goes here eventually
}
}
I'm pretty sure that it has something to do with calling Keypad() in main, but I have no idea how to call it and get things to display. I have to create the panels in the constructor, otherwise I can't add ActionListener, but now I don't know how to get them into frame.
Thanks for any help, and I'm hoping it's just something small and stupid I'm forgetting.
Changes i made to your code were changing the constructor to a method returning a JPanel and some very minor changes. You should notice that now the function returns a JPanel which fixes your problem.
Check this
import java.awt.*; //Import everything
import java.util.*;
import java.awt.event.*;
import javax.swing.*; //Seriously, everything, just makes this easier
public class Keypad extends JPanel implements ActionListener {
public static void main(String[] args) {
//Create the frame that holds everything else
JFrame frame = new JFrame ("Almost Functional Keypad");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
//Create the keypad
frame.getContentPane().add(getKeypad());
//Stuff to do so it won't break
frame.setPreferredSize(new Dimension(350,400));
frame.pack();
frame.setVisible(true);
frame.setResizable(false);
}
public static JPanel getKeypad(){
//Create the array of JPanels and labels
Keypad obj = new Keypad();
JButton[] keyList = new JButton[12];
JLabel[] keyLabel = new JLabel[12];
//Array with the key labels
String[] keyLabelText = {"1","2","3","4","5","6","7","8","9","*","0","#"};
//We need a counter
int i;
//Create the panels
for (i=0; i<12; i++){
keyList[i]= new JButton();
keyList[i].setPreferredSize (new Dimension(100, 75));
keyLabel[i] = new JLabel (keyLabelText[i]);
keyList[i].add (keyLabel[i]);
keyList[i].addActionListener(obj);
}
//Text field that only the buttons can modify
JTextArea displayText = new JTextArea();
displayText.setPreferredSize(new Dimension(320, 20));
//Create the "clear" button
JButton clear = new JButton();
clear.setPreferredSize(new Dimension(300, 40));
JLabel clearLabel = new JLabel ("Clear");
clear.add(clearLabel);
clear.addActionListener(obj);
// Set up primary panel
JPanel primary = new JPanel();
primary.add(displayText);
for (i=0; i<12; i++){
primary.add (keyList[i]);
}
primary.add(clear);
return primary;
}
public void actionPerformed (ActionEvent event){
//Stuff goes here eventually
// use it like this
//if(event.getSource()==whateveryouwanttotest){
//
//}
}
}
Picture included I have another issue where my buttons go to the top-right after the user inputs their name. At this point, text shows up in the GUI on the LEFT side of the center which seems it would be "WEST" when I put "CENTER". Code:
public TheDungeon()
{
setTitle("InsertGameNameHere");
setSize(750, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
setLocationRelativeTo(null);
buildButtonPanel();
characterInfoPanel = new JLabel("<html>Character information will go here</html>");
gameScreen = new JLabel();
inventoryPanel = new JLabel("<html>This is for the inventory</html>");
add(gameScreen, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
setVisible(true);
//Program run
userName();
gameScreen.setText("<html>Welcome "+name+", to the game that has no name!</html>");
classWindow();
}
private void buildButtonPanel()
{
// Create a panel for the buttons.
buttonPanel = new JPanel();
// Create the buttons.
b1 = new JButton("Button 1");
b2 = new JButton("Button 2");
b3 = new JButton("Button 3");
b4 = new JButton("Button 4");
b5 = new JButton("Button 5");
// Add the buttons to the button panel.
buttonPanel.add(b1);
buttonPanel.add(b2);
buttonPanel.add(b3);
buttonPanel.add(b4);
buttonPanel.add(b5);
}
private void userName() {
name = JOptionPane.showInputDialog("What will your name be?");
}
I'm not sure why your program is behaving as it seems to be since when I ran it, it did not do this. You may wish to check your code to make sure that it's the code you're posting here. But regardless, I do have some suggestions:
Best to not set the sizes of anything, but rather to let the components and the layout managers do this for you.
Consider if you must overriding getPreferredSize() if you need to control the size of a component more fully.
Call pack() on your top level window after adding all components and before calling setVisible(true). This will tell the layout managers to do their things.
Avoid extending JFrame since you will rarely need to override one of its innate behaviors.
If you do add or remove components, or change their preferredSizes somehow after rendering your top-level window, you will want to call revalidate() and then repaint() on the component's container to have the container re-layout the components it holds and then redraw them.
For example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
public class TheDungeon2 extends JPanel {
private static final int PREF_W = 750;
private static final int PREF_H = 600;
private static final String[] BUTTON_LABELS = {"Button 1", "Button 2",
"Button 3", "Button 4", "Button 5"};
private static final String WELCOME_TEXT = "Welcome %s to the game that has no name!";
private JLabel welcomeLabel = new JLabel("", SwingConstants.CENTER);
private String name;
public TheDungeon2() {
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
for (String buttonLabel : BUTTON_LABELS) {
JButton button = new JButton(buttonLabel);
buttonPanel.add(button);
}
setLayout(new BorderLayout());
add(welcomeLabel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.PAGE_END);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void getAndSetName() {
name = JOptionPane.showInputDialog(this, "What will your name be?");
welcomeLabel.setText(String.format(WELCOME_TEXT, name));
}
private static void createAndShowGui() {
TheDungeon2 dungeon2 = new TheDungeon2();
JFrame frame = new JFrame("Nameless Game");
dungeon2.getAndSetName();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(dungeon2);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I tested your code with an empty classWindow() method and the buttons are correctly placed in south,
for the CENTER issue, you should place something in WEST to have your text centred (even an empty panel) otherwise CENTER will take all the place,
look at this , i added this line :
add(new JButton("a button for test"),BorderLayout.WEST);
and here is the result :