I have ran into yet another issue. I am trying to set the text of a JTextField from another java class, and it does not seem to work.
I have tried the following:
calling the setter from inside the GUI class to .setText with a String. WORKS!
Setting the JTextField to some text so it isnt NULL -failed
Calling another method inside the GUI class, pass the string, then call the setter for the JTextField to set its text to the string. -failed (Just an idea i wanted to play with)
I did insure that the string is passed into the setter method by using a println. WORKED.
From googling around I believe that i have not set the reference to the main GUI?
Here is the GUI Class:
package book;
import book.BookIO;
import java.awt.BorderLayout;
import java.awt.*;
import javax.swing.*;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
/**
*
*
*/
public class UserInterface implements ActionListener {
//Containers
JFrame frame = new JFrame("Ye old Book stoppe");
JPanel toppane = new JPanel(new GridBagLayout());
JPanel bottomPane = new JPanel(new GridBagLayout());
//Buttons
JButton processItem = new JButton("Process Item #1");
JButton confirmItem = new JButton("Confirm Item #1");
JButton viewOrder = new JButton("View Order");
JButton finishOrder = new JButton("Finish Order ");
JButton newOrder = new JButton("New Order");
JButton exit = new JButton("Exit");
//TextFields
JTextField amount = new JTextField();
JTextField id = new JTextField();
JTextField quantity = new JTextField();
JTextField info = new JTextField("");
JTextField total = new JTextField();
//Labels
JLabel num = new JLabel("Enter Number of Items in this Order:");
JLabel bookID = new JLabel("Enter Book ID for Item #1:");
JLabel quantityItem = new JLabel("Enter Quantity for Item #1:");
JLabel itemInfo = new JLabel("Item #1:");
JLabel subtotal = new JLabel("Order subtotal for 0 Items(s):");
public void startUI() {
UserInterface gui = new UserInterface();
gui.bookingUI();
}
public void bookingUI() {
//sets windows, and pane in the UI
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagConstraints c = new GridBagConstraints();
frame.setSize(800, 300);
//adding the labels to the panel
c.insets = new Insets(5, 0, 0, 0);
c.gridx = 2;
c.gridy = 1;
toppane.add(num, c);
c.gridx = 2;
c.gridy = 2;
toppane.add(bookID, c);
c.gridx = 2;
c.gridy = 3;
toppane.add(quantityItem, c);
c.gridx = 2;
c.gridy = 4;
toppane.add(itemInfo, c);
c.gridx = 2;
c.gridy = 5;
toppane.add(subtotal, c);
toppane.setBackground(Color.GREEN);
frame.add(toppane);
//add textfield to panel
c.ipadx = 400;
c.insets = new Insets(5, 10, 0, 0);
c.gridx = 3;
c.gridy = 1;
toppane.add(amount, c);
c.gridx = 3;
c.gridy = 2;
toppane.add(id, c);
c.gridx = 3;
c.gridy = 3;
toppane.add(quantity, c);
c.gridx = 3;
c.gridy = 4;
toppane.add(info, c);
c.gridx = 3;
c.gridy = 5;
toppane.add(total, c);
//----------------------------------------------------------BUTTOM PANE-------------------------
//adding the buttons to the pane.---------------------------------------------------------------
GridBagConstraints b = new GridBagConstraints();
b.insets = new Insets(5, 5, 5, 5);
b.ipadx = 10;
b.ipady = 10;
b.gridx = 1;
b.gridy = 0;
bottomPane.add(processItem, b);
processItem.addActionListener(this);
b.gridx = 2;
b.gridy = 0;
bottomPane.add(confirmItem, b);
confirmItem.setEnabled(false);
confirmItem.addActionListener(this);
b.gridx = 3;
b.gridy = 0;
bottomPane.add(viewOrder, b);
viewOrder.setEnabled(true);
viewOrder.addActionListener(this);
b.gridx = 4;
b.gridy = 0;
bottomPane.add(finishOrder, b);
finishOrder.setEnabled(true);
finishOrder.addActionListener(this);
b.gridx = 5;
b.gridy = 0;
bottomPane.add(newOrder, b);
newOrder.addActionListener(this);
b.gridx = 6;
b.gridy = 0;
bottomPane.add(exit, b);
exit.addActionListener(this);
bottomPane.setBackground(Color.BLUE);
frame.add(bottomPane, BorderLayout.SOUTH);
frame.setSize(810, 310);
frame.setVisible(true);
}
//action listener for the buttons
public void actionPerformed(ActionEvent e) {
if (e.getSource() == processItem) {
confirmItem.setEnabled(true);
processItem.setEnabled(false);
BookIO findInfo = new BookIO();
findInfo.readFile(id.getText());
} else if (e.getSource() == confirmItem) {
processItem.setEnabled(true);
confirmItem.setEnabled(false);
} else if (e.getSource() == viewOrder) {
} else if (e.getSource() == finishOrder) {
} else if (e.getSource() == newOrder) {
} else if (e.getSource() == exit) {
System.exit(0);
}
}
//Creating getters and setters to change the text for the buttons and labels, as well as getting text from the textfields.
public void setProcessItemBtn(int num) {
processItem.setText("Process Item #" + num);
processItem.validate();
processItem.repaint();
}
public void setConfirmItemBtn(int num) {
confirmItem.setText("Confirm Item #" + num);
confirmItem.validate();
confirmItem.repaint();
}
public void setViewOrderBtn(String title) {
viewOrder.validate();
viewOrder.repaint();
}
public void setInfo(String title) {
System.out.println(title);
info.setText(title);
info.validate();
info.repaint();
}
public String getAmount() {
String str = amount.getText();
return str;
}
}
Here is the class with the method call to the setter:
package book;
import book.UserInterface;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Objects;
import java.util.StringTokenizer;
/**
*
*
*/
public class BookIO {
public void readFile(String bookID) {
try {
FileReader read = new FileReader("inventory.txt");
BufferedReader buffer = new BufferedReader(read);
StringBuffer stringBuff = new StringBuffer();
String line, delim = "[,]";
for (int i = 0; i < 12; i++) {
line = buffer.readLine();
String[] tokens = line.split(delim);
if ((Objects.equals(tokens[0], bookID)) == true) {
UserInterface setInfo = new UserInterface();
setInfo.setInfo(tokens[1]);
}
}
} catch (IOException e) {
System.out.println("Error starting file!");
}
}
}
Your error is that you are instantiating a new UserInterface object which is wrong:
UserInterface setInfo = new UserInterface();
setInfo.setInfo(tokens[1]);
Your readFile() from BookIO should be like this:
public static void readFile(String bookID, UserInterface userInterface) {
try {
FileReader read = new FileReader("inventory.txt");
BufferedReader buffer = new BufferedReader(read);
StringBuffer stringBuff = new StringBuffer();
String line, delim = "[,]";
for (int i = 0; i < 12; i++) {
line = buffer.readLine();
String[] tokens = line.split(delim);
if ((Objects.equals(tokens[0], bookID)) == true) {
userInterface.setInfo(tokens[1]);
}
}
} catch (IOException e) {
System.out.println("Error starting file!");
}
}
In your UserInterface class, where you have this:
BookIO findInfo = new BookIO();
findInfo.readFile(id.getText());
Change the lines to this:
//pass the already created userInterface object.
BookIO.readFile(id.getText(), this);
Note: I have tested this and it worked. Tell me if it doesn't work for you.
You always make a new UserInterface instance
UserInterface setInfo = new UserInterface();
setInfo.setInfo(tokens[1]);
That sounds incorrect. Normally you would only have one such unstance (the visible one), and update that one.
Small side-note
if( Objects.equals(tokens[0], bookID)) == true )
can be simplified to
if( Objects.equals(tokens[0], bookID)) )
Related
I'm trying to make a simple GUI program that can be used to make multiple choices inside a game. I understand that I have to take all the questions, their choices, and the right answer as well. My problem is that when I try to collect the right answers in the hashmap, I get only the last true answer and its duplicated within the hashmap. In addition, I received a problem when collecting choices and solved the issue with an unusual for-loop, but unfortunately I couldn't do that with answers.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
public class ExamFrame extends JFrame {
private ExamPanel examPanel;
private static int count = 1;
static HashMap<Integer,ArrayList<String>> choicesMap = new HashMap<>();
static ArrayList<String> choicesList = new ArrayList<>();
static HashMap<Integer,ArrayList<String>> truesMap = new HashMap<>();
static ArrayList<String> truesList = new ArrayList<>();
static ArrayList<String> prompts = new ArrayList<>();
public ExamFrame() {
super("Making exam");
examPanel = new ExamPanel();
setContentPane(examPanel);
setSize(700,600);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
class ExamPanel extends JPanel implements ActionListener{
private JLabel quLabel;
private JTextField questionField;
private ArrayList<JCheckBox> jCheckBoxes;
private ArrayList<JTextField> respnsesFields;
private JButton suivant,terminer;
private JPanel centerPanel;
public ExamPanel() {
centerPanel = new JPanel(new BorderLayout());
suivant = new JButton("next");
suivant.addActionListener(this);
terminer = new JButton("Finish");
terminer.setEnabled(false);
terminer.addActionListener(this);
layoutComponents();
}
public void layoutComponents() {
setBackground(Color.green);
setLayout(new BorderLayout());
JPanel prince = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.NONE;
prince.setBackground(Color.CYAN);
gc.gridy = 0;
gc.weightx = 1;
gc.weighty = 0.1;
gc.insets = new Insets(0, 0, 0, 5);
gc.anchor = GridBagConstraints.LINE_END;
gc.gridx = 0;
quLabel = new JLabel("Question: ");
prince.add(quLabel,gc);
gc.gridx = 1;
gc.insets = new Insets(0, 0, 0, 0);
gc.anchor = GridBagConstraints.LINE_START;
questionField = new JTextField(45);
prince.add(questionField, gc);
jCheckBoxes = new ArrayList<>();
respnsesFields = new ArrayList<>();
for (int j = 0; j<2; j++) {
JCheckBox jCheckBox= new JCheckBox("Reponse "+(j+1));
jCheckBoxes.add(jCheckBox);
gc.gridy++;
gc.weightx = 1;
gc.weighty = 0.1;
gc.insets = new Insets(0, 0, 0, 5);
gc.anchor = GridBagConstraints.LINE_END;
gc.gridx=0;
prince.add(jCheckBox,gc);
JTextField jTextField = new JTextField(40);
respnsesFields.add(jTextField);
gc.gridx=1;
gc.insets = new Insets(0, 0, 0, 0);
gc.anchor = GridBagConstraints.LINE_START;
prince.add(jTextField,gc);
}
gc.gridy++;
gc.weightx = 1;
gc.weighty = 0.1;
gc.insets = new Insets(0, 0, 0, 5);
gc.anchor = GridBagConstraints.LINE_END;
gc.gridx=0;
prince.add(suivant,gc);
gc.gridx=1;
gc.insets = new Insets(0, 0, 0, 0);
gc.anchor = GridBagConstraints.LINE_START;
prince.add(terminer,gc);
centerPanel.add(prince,BorderLayout.CENTER);
add(centerPanel,BorderLayout.CENTER);
}
public void actionPerformed(ActionEvent e) {
suivant.setEnabled(false);
if (count<=3) { //3 == Number of questions
suivant.setEnabled(true);
if (e.getSource() == suivant) {
String prompt = questionField.getText();
prompts.add(prompt);
ExamPanel.this.setVisible(false);
ExamFrame.this.setContentPane(new ExamPanel());
for (int i=0;i<2;i++) { //2 == Number of choices
choicesList.add(respnsesFields.get(i).getText());
}
for (int i=0;i<2;i++) {
if (jCheckBoxes.get(i).isSelected()) {
truesList.add(respnsesFields.get(i).getText());
}
}
truesMap.put(count,truesList);
truesList.clear();
count++;
}
}
else {
terminer.setEnabled(true);
questionField.setEnabled(false);
for (JTextField jTextField:respnsesFields) {
jTextField.setEnabled(false);
}
suivant.setEnabled(false);
if (e.getSource() == terminer) {
System.out.println(choicesList);
for (int i=0;i<3;i++) {
ArrayList<String> arrayList = new ArrayList<>();
for (int j=(i*2);j<(i+1)*2;j++) {
arrayList.add(choicesList.get(j));
}
choicesMap.put(i,arrayList);
}
System.out.println(choicesMap);
System.out.println(truesMap);
System.exit(0);
}
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ExamFrame();
}
});
}
}
You need to create a new ArrayList for each distinct item placed into the Map. Your program has only one truesList ArrayList instance that all Map items share. Inside of the ActionListener's actionPerformed method, create the new ArrayList (if one is needed -- if you're creating a new item to put into the Map), and place it into the Map along with the Integer key.
e.g.,
if (e.getSource() == suivant) {
truesList = new ArrayList<>(); // !! ADDED *****
String prompt = questionField.getText();
prompts.add(prompt);
ExamPanel.this.setVisible(false);
ExamFrame.this.setContentPane(new ExamPanel());
for (int i = 0; i < 2; i++) { // 2 == Number of choices
choicesList.add(respnsesFields.get(i).getText());
}
for (int i = 0; i < 2; i++) {
if (jCheckBoxes.get(i).isSelected()) {
truesList.add(respnsesFields.get(i).getText());
}
}
truesMap.put(count, truesList);
// !! truesList.clear(); // !! REMOVED ****
count++;
}
Side note: if you're using a Map<Integer, List<String>>, and the Integer key String is monotonically increasing as yours is, why use a Map at all? Why not simply use nested lists?
List<List<String>> truesList = new ArrayList<>();
The index of the outside list will be the same as the Integer key for the HashMap.
package committeeGUI;
import static committeeGUI.CommitteeGUI.comList;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class StudentMemberFrame extends JFrame {
public StudentMemberFrame() {
super("Add Student");
setSize(450, 500);
setLocation(561, 150);
super.setResizable(false);
addStudentMember();
}
public void addStudentMember() {
CommitteeGUI.frame.setEnabled(false);
final JPanel showConsoleArea = new JPanel(new FlowLayout(FlowLayout.LEFT));
showConsoleArea.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//creating border and size of the border
showConsoleArea.setBorder(BorderFactory.createLineBorder(Color.black, 3));
add(showConsoleArea); //, BorderLayout.CENTER);
//setting a size to showConsoleArea.
showConsoleArea.setSize(500, 500);
final JLabel lblheading = new JLabel("STUDENT");
// showConsoleArea.add(lblheading,BorderLayout.CENTER);
/*
* creating components of company form
*/
final JLabel lblCommitteeName = new JLabel("Committee name");
final JTextField txtName = new JTextField(15);
final JLabel lblMemberName = new JLabel("Student name");
final JTextField txtMemberName = new JTextField(15);
final JLabel lblMemberNumber = new JLabel("Student number");
final JTextField txtMemberNumber = new JTextField(15);
final JLabel lblMemberCourse = new JLabel("Student course");
final JTextField txtMemberCourse = new JTextField(15);
final JButton buttAdd = new JButton("SAVE");
final JButton buttCancel = new JButton("CANCEL");
// adding components to the display area
c.gridx = 1;
c.gridy = 0;
showConsoleArea.add(lblheading, c);
c.gridx = 0;
c.gridy = 1;
showConsoleArea.add(lblCommitteeName, c);
c.gridx = 1;
c.gridy = 1;
showConsoleArea.add(txtName, c);
c.gridx = 0;
c.gridy = 2;
showConsoleArea.add(lblMemberName, c);
c.gridx = 1;
c.gridy = 2;
showConsoleArea.add(txtMemberName, c);
c.gridx = 0;
c.gridy = 3;
showConsoleArea.add(lblMemberNumber, c);
c.gridx = 1;
c.gridy = 3;
showConsoleArea.add(txtMemberNumber, c);
c.gridx = 0;
c.gridy = 4;
showConsoleArea.add(lblMemberCourse, c);
c.gridx = 1;
c.gridy = 4;
showConsoleArea.add(txtMemberCourse, c);
c.gridx = 0;
c.gridy = 5;
showConsoleArea.add(buttAdd, c);
c.gridx = 1;
c.gridy = 5;
showConsoleArea.add(buttCancel, c);
/*
* able to displaying the company frame
*/
this.show();
buttAdd.addActionListener((ActionEvent e) -> {
if (txtName.getText().equals("")
|| txtMemberName.getText().equals("")
|| txtMemberNumber.getText().equals("")
|| txtMemberCourse.getText().equals("")) //validating the data
{
CommitteeGUI.frame.setEnabled(false);
setEnabled(false);
messagebox("Enter a valid data", 0);
return;
}
if (!txtMemberNumber.getText().matches("\\d+")) {
CommitteeGUI.frame.setEnabled(false);
setEnabled(false);
messagebox("Member number must be a integer", 0);
return;
}
for (Committee com : comList) {
if (com.getName().equals(txtName.getText())) {
Student st = new Student();
st.setName(txtMemberName.getText());
st.setAcademicNo(Integer.parseInt(txtMemberNumber.getText()));
st.setCourse(txtMemberCourse.getText());
com.memberList.add(st);
messagebox("Member added successfully", 1);
setEnabled(false);
return;
}
}
messagebox("No Committee found with given name", 1);
});
//creating ActionListner to Cancel button
buttCancel.addActionListener((ActionEvent e) -> {
//frame is enabled for user.
CommitteeGUI.frame.setEnabled(true);
dispose(); //disposing the frame
} //pass the action to actionPerformed method and perform it.
);
}
#SuppressWarnings("deprecation")
public void messagebox(String label, final int conform) {
final JDialog infoBox = new JDialog();//message box
infoBox.setSize(400, 90);
infoBox.setAlwaysOnTop(true);
infoBox.setResizable(false);
infoBox.setLocation(675, 258);
JLabel space = new JLabel(" ");
JLabel label1 = new JLabel(label);
JButton buttOk = new JButton("Ok");
buttOk.addActionListener((ActionEvent e) -> {
if (conform == 1) {
// making frame operation enable.
CommitteeGUI.frame.setEnabled(true);
dispose();
}
setEnabled(true);
infoBox.hide();
});
JPanel holder = new JPanel(new FlowLayout());
holder.add(label1);
holder.add(buttOk);
infoBox.add(holder);
infoBox.show();
}
}
Above is my code. I want to put space between the heading (STUDENT) and the fields.
Attached is the snapshot of the frame:
I am not familiar with this layout. Help is much appreciated.
public void addStudentMember() {
final JPanel showConsoleArea = new JPanel(new FlowLayout(FlowLayout.LEFT));
showConsoleArea.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
// Add below line of code change appropriate spacing
c.insets = new Insets(10, 10, 10, 10);
I'm running into a problem, I believe with the actionlistener. The weird thing is that it works on some computers and not on others. All computers are running JE7.1. So, on some systems, it works flawlessly, the user enters text, presses enter and the text is appended to the JTextPane and updates the static userInput variable. On other computers though, text is appended, but the variable never seems to update.
For example:
user types in "Hello"
"Hello is appened to the JtextPane and the static variable userInput = "Hello"
Am I missing something very silly here? Thank you in advance.
package com.core;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.text.*;
public class GUI {
public static JFrame f;
private static JPanel topPanel = new JPanel();
private static JTextPane textArea = new JTextPane();
public static JTextField inputText = new JTextField();
private static String userInput = "";
private static Player player;
public static JPanel sidePanel = new JPanel();
public JFrame buildFrame(){
f = new JFrame("AMSA World");
f.setSize(800, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridBagLayout());
textArea.setFocusable(false);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
String text = inputText.getText();
if(!text.equals("")){
appendToPane(text + "\n\n", Color.blue);
inputText.setText("");
if(text.startsWith("use ")){
ArrayList<Item> inventory = player.getInventory();
String key = text.substring(4);
boolean found = false;
for(Item i : inventory){
if(i.getName().equalsIgnoreCase(key)){
found = true;
i.use();
break;
}
}
if(!found){
appendToPane("Item does not exist in your iventory.\n\n", Color.black);
}
}
if(text.startsWith("inventory")){
ArrayList<Item> inventory = player.getInventory();
if(inventory.size() > 0){
for(Item i : inventory){
appendToPane(i.getName() +"\n", Color.darkGray);
}
}
else
appendToPane("Your iventory is empty.\n\n", Color.black);
appendToPane("#", Color.blue);
}
else{
userInput = text;
}
}
}
};
inputText.addActionListener(listener);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(5,5,5,5);
c.weightx = 1.0;
c.gridwidth = 3;
c.weighty = 0.025;
c.gridx = 0;
c.gridy = 0;
f.add(topPanel, c);
c.fill = GridBagConstraints.BOTH;
c.weighty = 1.0;
c.gridwidth = 2;
c.gridx = 0;
c.gridy = 1;
f.add(scrollPane, c);
c.fill = GridBagConstraints.BOTH;
c.weighty = 1.0;
c.gridwidth = 1;
c.gridx = 2;
c.gridy = 1;
f.add(sidePanel, c);
sidePanel.setVisible(false);
c.fill = GridBagConstraints.HORIZONTAL;
c.weighty = 0.025;
c.gridwidth = 3;
c.gridx = 0;
c.gridy = 2;
f.add(inputText, c);
f.setVisible(true);
return f;
}
public static JTextField getTextField(){
return inputText;
}
public static void toggleTextField(boolean value){
inputText.setEnabled(value);
}
public static String getUserInput(){
return userInput;
}
public static void setUserInput(String s){
userInput = s;
}
public static JPanel getTopPanel(){
return topPanel;
}
public static JPanel getSidePanel(){
return sidePanel;
}
public static void setPlayer(Player p){
player = p;
}
public static void appendToPane(String msg, Color c){
if(inputText.isEnabled()){
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);
textArea.setCharacterAttributes(aset, false);
textArea.replaceSelection(msg);
textArea.setCaretPosition(textArea.getDocument().getLength());
}
}
}
To (try) to answer your question, I'm guessing you are running into multi-thread issues. Swing events run in their own thread thread, the Event Dispatch Thread. If you are accessing the variable from another thread, you will run into occasional situations where the variables are not synchronized between threads.
In the bigger picture, taking shortcuts in writing Java code will generally end up costing you a lot of time and effort. Placing your entire UI in static variables with static methods is not a good idea. Take the time to instantiate an instance. Beyond that, I'm guessing you didn't start the UI using SwingUtilities.invokeLater(). Read the Swing Tutorial, which I linked above. Swing works well, but it is not simple.
I have a basic gui (it doesn't need to look pretty, it just needs to work. It's a gui to display several algorithms I'm implementing for my thesis.) but the checkboxes and button won't show up randomly. Sometimes they appear, sometimes they don't. I honestly have no clue why this could be happening and I'm pretty scrub at swing, so I'm lost.
EDIT: Here's what i want my gui to look like:
//import java.awt.*;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.*;
import javax.swing.ButtonGroup;
import javax.swing.*; //notice javax
public class MapWindowController extends JFrame implements ActionListener, ItemListener
{
private static final int WIDTH = 600, HEIGHT = 800;
private static final int SETTINGS_WIDTH = 600, SETTINGS_HEIGHT = 200;
private static final int NUM_MAP_TYPE = 2;
private static final int NUM_ALGORITHM_TYPE = 4;
private static final int MAP_IMAGE_SIZE = 400, ACTUAL_MAP_SIZE = 10;
private JButton run;
private JCheckBox[] map_type;
private JCheckBox[] algorithm_type;
JPanel panel = new JPanel();
JPanel settings_panel = new JPanel();
MapView map_view = new MapView(MAP_IMAGE_SIZE);
SettingsButtonsPanel settings = new SettingsButtonsPanel();
MapModel map_model = new MapModel(ACTUAL_MAP_SIZE, map_view);
ButtonGroup bgMap;
ButtonGroup bgAlgorithm;
public MapWindowController()
{
setLocationRelativeTo(null);
setTitle("HPA* Test");
setSize(WIDTH, HEIGHT);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(panel);
panel.setBounds(0, 0, 600, 800);
panel.setLayout(null);
/*GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;*/
instantiateSettingsPanel();
//panel.add(settings);
/*c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;*/
panel.add(map_view);
map_view.setBounds(0,200,600,600);
//button_panel.setBounds(0,0);
map_view.repaint();
}
public void instantiateSettingsPanel() {
settings_panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//this.setLayout(null);
map_type = new JCheckBox[NUM_MAP_TYPE];
map_type[0] = new JCheckBox("Sparse");
map_type[0].setSelected(true);
map_type[1] = new JCheckBox("Maze");
map_type[1].setSelected(false);
algorithm_type = new JCheckBox[NUM_ALGORITHM_TYPE];
algorithm_type[0] = new JCheckBox("A*");
algorithm_type[0].setSelected(true);
algorithm_type[1] = new JCheckBox("HPA*");
algorithm_type[1].setSelected(false);
algorithm_type[2] = new JCheckBox("TA*");
algorithm_type[2].setSelected(true);
algorithm_type[3] = new JCheckBox("PTHPA*");
algorithm_type[3].setSelected(false);
bgMap = new ButtonGroup( );
bgAlgorithm = new ButtonGroup( );
settings_panel.setMaximumSize(new Dimension(600,200));
for(int i = 0; i < NUM_MAP_TYPE; i++)
{
bgMap.add(map_type[i]);
map_type[i].addItemListener(this);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = i+1;
settings_panel.add(map_type[i], c);
}
for(int i = 0; i < NUM_ALGORITHM_TYPE; i++)
{
bgAlgorithm.add(algorithm_type[i]);
algorithm_type[i].addItemListener(this);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = i+1;
settings_panel.add(algorithm_type[i], c);
}
run = new JButton("Run");
run.addActionListener(this);
settings_panel.add(run);
panel.add(settings_panel);
settings_panel.setBounds(0,0,SETTINGS_WIDTH,SETTINGS_HEIGHT);
}
public void itemStateChanged(ItemEvent e)
{
Object source = e.getItemSelectable();
//if(source == )
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
String algorithm = "A*";
String map = "Sparse";
for(int i = 0; i < algorithm_type.length; i++) {
if(algorithm_type[i].isSelected()) {
algorithm = algorithm_type[i].getText();
break;
}
}
for(int i = 0; i < map_type.length; i++) {
if(map_type[i].isSelected()) {
map = map_type[i].getText();
break;
}
}
if(source == run) {
if(map.equals("Sparse"))
map_model.createRandomObstaclesSparse(10, 1);
else
map_model.createRandomObstaclesMaze(1);
map_model.startPathfinding(algorithm, 0, true);
map_view.setMapScale(ACTUAL_MAP_SIZE);
map_view.setMapModel(map_model);
}
}
}
Your first mistake is using a null layout, your second mistake is calling setVisible before the UI is completed.
Your basic idea is sound, separating the various areas of responsibility into separate components, this will make you life much easier.
Basically, I used a GridBagLayout as it allows you to define fill weights for each component, providing a 1/4 of the vertical space to the buttons and the remainder to the map...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MapWindowController extends JFrame implements ActionListener, ItemListener {
private static final int WIDTH = 600, HEIGHT = 800;
private static final int SETTINGS_WIDTH = 600, SETTINGS_HEIGHT = 200;
private static final int NUM_MAP_TYPE = 2;
private static final int NUM_ALGORITHM_TYPE = 4;
private static final int MAP_IMAGE_SIZE = 400, ACTUAL_MAP_SIZE = 10;
private JButton run;
private JCheckBox[] map_type;
private JCheckBox[] algorithm_type;
JPanel content = new JPanel();
JPanel settings_panel = new JPanel();
private JPanel mapPane = new JPanel(new BorderLayout());
ButtonGroup bgMap;
ButtonGroup bgAlgorithm;
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) {
}
new MapWindowController();
}
});
}
public MapWindowController() {
setLocationRelativeTo(null);
setTitle("HPA* Test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
content.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weighty = 0.25;
gbc.weightx = 1;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
content.add(settings_panel, gbc);
gbc.gridy++;
gbc.weighty = 0.75;
content.add(mapPane, gbc);
try {
mapPane.add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/Map.png")))));
} catch (IOException ex) {
ex.printStackTrace();
}
add(content);
/*GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;*/
instantiateSettingsPanel();
//panel.add(settings);
/*c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;*/
pack();
setLocationByPlatform(true);
setVisible(true);
}
public void instantiateSettingsPanel() {
settings_panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//this.setLayout(null);
map_type = new JCheckBox[NUM_MAP_TYPE];
map_type[0] = new JCheckBox("Sparse");
map_type[0].setSelected(true);
map_type[1] = new JCheckBox("Maze");
map_type[1].setSelected(false);
algorithm_type = new JCheckBox[NUM_ALGORITHM_TYPE];
algorithm_type[0] = new JCheckBox("A*");
algorithm_type[0].setSelected(true);
algorithm_type[1] = new JCheckBox("HPA*");
algorithm_type[1].setSelected(false);
algorithm_type[2] = new JCheckBox("TA*");
algorithm_type[2].setSelected(true);
algorithm_type[3] = new JCheckBox("PTHPA*");
algorithm_type[3].setSelected(false);
bgMap = new ButtonGroup();
bgAlgorithm = new ButtonGroup();
settings_panel.setMaximumSize(new Dimension(600, 200));
for (int i = 0; i < NUM_MAP_TYPE; i++) {
bgMap.add(map_type[i]);
map_type[i].addItemListener(this);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = i + 1;
settings_panel.add(map_type[i], c);
}
for (int i = 0; i < NUM_ALGORITHM_TYPE; i++) {
bgAlgorithm.add(algorithm_type[i]);
algorithm_type[i].addItemListener(this);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = i + 1;
settings_panel.add(algorithm_type[i], c);
}
run = new JButton("Run");
run.addActionListener(this);
settings_panel.add(run);
}
public void itemStateChanged(ItemEvent e) {
Object source = e.getItemSelectable();
//if(source == )
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
String algorithm = "A*";
String map = "Sparse";
for (int i = 0; i < algorithm_type.length; i++) {
if (algorithm_type[i].isSelected()) {
algorithm = algorithm_type[i].getText();
break;
}
}
for (int i = 0; i < map_type.length; i++) {
if (map_type[i].isSelected()) {
map = map_type[i].getText();
break;
}
}
if (source == run) {
// if (map.equals("Sparse")) {
// map_model.createRandomObstaclesSparse(10, 1);
// } else {
// map_model.createRandomObstaclesMaze(1);
// }
// map_model.startPathfinding(algorithm, 0, true);
// map_view.setMapScale(ACTUAL_MAP_SIZE);
// map_view.setMapModel(map_model);
}
}
}
Don't use setSize of setBounds on a window, instead, use pack to automatically set the optimal size of the window based on it's contents preferred size.
Could you please help me use the ActionListener correclty in my code? The code compiles and the GUI is displayed correctly, but no button works!! If you want to test the code, note that you need to put the image in the same folder as the project file created and change the line "ImageIcon myImageIcon = new ImageIcon("rodeo.jpg");" according to the name of your photo.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ImageApplication extends JFrame implements ActionListener
{
public Image myImage;
public JLabel myImageLabel;
public ImageIcon myImageIcon;
public JFrame frame;
public JTextField txtWidth, txtHeight;
public int origWidth, origHeight;
public static void main(String[] args)
{
int origWidth, origHeight;
ImageApplication ia = new ImageApplication();
ia.setVisible(true);
JFrame frame = new JFrame();
ImageIcon myImageIcon = new ImageIcon("rodeo.jpg");
JLabel myImageLabel = new JLabel(myImageIcon, JLabel.CENTER);
Image myImage = myImageIcon.getImage();
origWidth = myImageIcon.getIconWidth();
origHeight = myImageIcon.getIconHeight();
JMenuBar myMenuBar = new JMenuBar();
JMenu myMenu = new JMenu("Options");
JMenuItem myMenuItem1 = new JMenuItem("Double");
JMenuItem myMenuItem2 = new JMenuItem("Reset");
myMenu.add(myMenuItem1);
myMenu.add(myMenuItem2);
myMenuBar.add(myMenu);
ia.setJMenuBar(myMenuBar);
JButton bAL = new JButton("Align Left");
JButton bAC = new JButton("Align Center");
JButton bAR = new JButton("Align Right");
JButton bResize = new JButton ("Resize");
bAL.setFocusPainted(false);
bAC.setFocusPainted(false);
bAR.setFocusPainted(false);
bResize.setFocusPainted(false);
JLabel lWidth = new JLabel("Width:");
JLabel lHeight = new JLabel("Height:");
JTextField txtWidth = new JTextField(Integer.toString(origWidth));
JTextField txtHeight = new JTextField(Integer.toString(origHeight));
JPanel GRID = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1f;
c.weighty = 0f;
c.gridx = 0;
c.gridy = 0;
GRID.add(bAL, c);
c.gridx++;
GRID.add(bAC, c);
c.gridx++;
GRID.add(bAR, c);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
GRID.add(myImageLabel, c);
c.gridwidth = 1;
c.gridx = 0;
c.gridy = 2;
GRID.add(lWidth, c);
c.gridx++;
c.gridwidth = 2;
GRID.add(txtWidth, c);
c.gridwidth = 1;
c.gridx = 0;
c.gridy = 3;
GRID.add(lHeight, c);
c.gridx++;
c.gridwidth = 2;
GRID.add(txtHeight, c);
c.gridwidth = 1;
c.gridx = 0;
c.gridy = 4;
GRID.add(bResize, c);
ia.add(GRID, BorderLayout.CENTER);
ia.setSize(origWidth + 150, origHeight + 150);
myMenuItem1.addActionListener(ia);
myMenuItem1.setActionCommand("double");
myMenuItem2.addActionListener(ia);
myMenuItem2.setActionCommand("reset");
bAL.addActionListener(ia);
bAL.setActionCommand("left");
bAC.addActionListener(ia);
bAC.setActionCommand("center");
bAR.addActionListener(ia);
bAR.setActionCommand("right");
bResize.addActionListener(ia);
bResize.setActionCommand("resize");
}
private void ResizeImage(int Width, int Height)
{
myImage = myImage.getScaledInstance(Width, Height, Image.SCALE_SMOOTH);
myImageIcon.setImage(myImage);
myImageLabel.setIcon(myImageIcon);
txtWidth.setText(Integer.toString(Width));
txtHeight.setText(Integer.toString(Height));
setSize(Width + 150, Height + 150);
}
public void actionPerformed(ActionEvent e)
{
String command = e.getActionCommand();
if(command == "left") myImageLabel.setHorizontalAlignment(JLabel.LEFT);
else if(command == "center") myImageLabel.setHorizontalAlignment(JLabel.CENTER);
else if(command == "right") myImageLabel.setHorizontalAlignment(JLabel.RIGHT);
else if(command == "resize") ResizeImage(Integer.parseInt(txtWidth.getText()),
Integer.parseInt(txtHeight.getText()));
else if(command == "double") ResizeImage(myImageIcon.getIconWidth() * 2,
myImageIcon.getIconHeight() * 2);
else if(command == "reset") ResizeImage(origWidth, origHeight);
}
}
Use String#equals to compare String content. You are using the == operator which compares Object references.
However, as the buttons have differing functionality, better for each to have an individual ActionListener. This can be done using an anonymous ActionListener instance.
Side issue: The class member variable myImageLabel is not being assigned. Rather another variable
with the same name is initialized in the static main method. You need to move all the components instantiated in the main method into an instance method and also remove the JLabel local class declaration.
After moving code:
JLabel myImageLabel = new JLabel(myImageIcon, JLabel.CENTER);
should be
myImageLabel = new JLabel(myImageIcon, JLabel.CENTER);
Try this method:
What it does: it adds to the button itself, when clicked an method to be performed:
buttonName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//do what ever
}
});
//set bunds for the button itself, if not done otherwise, but for your layout.
These instance variables:
public JTextField txtWidth, txtHeight;
are never initialized but are referred to in your listener code. You have local variables of the same name that you're instantiating. Change this:
JTextField txtWidth = new JTextField(Integer.toString(origWidth));
JTextField txtHeight = new JTextField(Integer.toString(origHeight));
to this:
txtWidth = new JTextField(Integer.toString(origWidth));
txtHeight = new JTextField(Integer.toString(origHeight));
and similarly for your other instance variables.
Use the following code to get Image
ImageIcon myImageIcon = new ImageIcon("rodeo.jpg").getImage();