I'm a little ignorant when it comes to events in Java, so I'm working on a project to help rectify that. As such, I am working on a project that is basically a pizzeria POS program. There's the main GUI, with the pre-configured "meal" options. I click on those, and their price and names are displayed in the JTable correctly. However, when I try doing that with a button in a different class, I get no errors and no entries into the JTable.
I'm using NetBeans GUI Builder btw.
This is currently what I have for the MainGUI class:
public class MainGUI extends javax.swing.JFrame {
public void getItems(String extName, double extPrice) {
itemName = extName; //instance variables
itemPrice = extPrice;
getTotal(itemPrice); //displays the total sum of items in textfield
orderTab.setValueAt(itemName, arrayCount, 0); //JTable.
orderTab.setValueAt(itemPrice, arrayCount, 1);
arrayCount++; //so next items clicked can displayed on next row
}
}
and for the other class
public class BuildPizzaGUI extends javax.swing.JFrame {
private void addButtonClick(java.awt.event.ActionEvent evt) {
MainGUI exporter = new MainGUI();
exporter.getItems(custName, custPrice);
setVisible(false); //closes window
}
}
I don't get any errors messages. I want the item name and price to be displayed, but currently, I don't get anything other than a closed window. Thanks.
MainGUI exporter = new MainGUI();
You can't keep creating a new instance of the MainGUI every time you click a button. If you do it means with every item you try to add you create a new JFrame.
Instead you need to pass a reference to the existing MainGUI class when you create your BuildPizzaGUI. Then when you click the button you reference this variable which will allow you to update the JTable in that class.
Related
What I want to achieve is very simple.
I have 2 classes. "SpeedingTicket" & "SpeedingTicket GUI".
Inside my GUI I have 1 textbox name txtSpeedLimit & a button.
Inside my SpeedingTicket class I have a variable "int speedingTicket".
Inside my SpeedingTicket class I also have a get & set method for "speedingTicket".
I know how to get and set text using JTextFields, but I want to be able to:
receive input from the "txtSpeedLimit", and store that value into the "txtSpeedLimit" instance variable in the "SpeedTicket" class. I can then check for validation etc when I come to adding the vehicle speed.
Maybe this isn't the most efficient way of dealing with this program. Maybe I should scrap the instance variables in SpeedingTicket, and deal with it all in the GUI.
Any advice would be hugely appreciated.
Basically what I'm trying to do is this:
class confirmHandler implements ActionListener{
public void actionPerformed(ActionEvent e){
String val = txtSpeedLimit.getText();
int realNum = speed.getSpeedLimit() = txtSpeedLimit; < but obviously that doesn't work, but I want the textbox link to the variable.
EDIT: If we take away the GUI, all I want my program to do is the following:
Speed Limit: 50 < enterd via textfield
Speed: 60 < entered via textfield
if the speed is blah blah (ive already coded this).. then output a result to one of my labels.
I achieved this without making a GUI and making it only console based, but instead of the user typing it via the console, I want it to be typed via textfields.
THe values that are entered into the textfields should be stored in the two variables (speed and speedlimit) that are in the SpeedingTicket class.
You can update a value in:
public class SpeedingTicket {
int speedingTicket;
public SpeedingTicket() {
speedingTicket = 500;
}
public int getSpeedingTicket() {
return speedingTicket;
}
}
by:
public class SpeedingTicketGUI extends JPanel{
SpeedingTicket st;
SpeedingTicketGUI() {
st = new SpeedingTicket();
setLayout(new FlowLayout(FlowLayout.LEFT));
JTextField txtField = new JTextField(10);
txtField.setText(""+st.getSpeedingTicket());
add(txtField);
JButton btn = new JButton("Update");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setSpeedingTicket(txtField.getText());
}
});
add(btn);
}
private void setSpeedingTicket(String text) {
try {
int speedTicket = Integer.parseInt(text);
st.setSpeedingTicket(speedTicket);
System.out.println("Speeding ticket set to " +st.getSpeedingTicket());
} catch (NumberFormatException ex) {
System.out.println("Invalid value " +text);
ex.printStackTrace();
}
}
public static void main(String[] args){
JFrame frame = new JFrame("Speeding Ticket");
frame.setSize(400,100);
frame.add(new SpeedingTicketGUI());
frame.setVisible(true);
}
}
You don't need to store values in JText or any GUI componenets...
Use global static variables. For example:
public static int speed_limit;
You can access this variable from ANY method,class, etc.
There are multiple ways to do it.
You can detect textfield changes by using a DocumentListener or if you want (not recommended) by a KeyListener.
The Listener could be implemented directly by your gui class or by your other class. If you want more abstraction you could implement the DocumentListener by your gui class and create a method
public void addSpeedChangeListener(SpeedChangeListener scl) {
this.speedChangeListeners.add(scl);
}
Your SpeedChangeListener could be very simple:
public interface SpeedChangeListener {
public void speedChanged(int value);
}
Then your second class implements the SpeedChangeListener and calls addSpeedChangeListener(this) on your gui class. Inside the gui class, your document listener calls speedChanged(val) for every listener registered.
EDIT
You can also use the Button and call the speedChanged on every listener inside the actionPerformed method of the ActionListener.
I think it would be easier to use a JOptionDialog which pop ups when the button is clicked. That way you can easily get input and also validate the input straight away.
I have a quick question. I don't get it...
I've got a JFrame where I add a JComboBox:
JComboBox<String> Team_ComboBox = new JComboBox<>();
Team_ComboBox_Handler ComboBox_Listener = new Team_ComboBox_Handler();
Team_ComboBox.addActionListener(ComboBox_Listener);
Team_ComboBox.addItem("Test 1");
Team_ComboBox.addItem("Test 2");
On this Frame I have a button which opens another JFrame.
Play = new JButton();
Play.setText("Play");
Play.setPreferredSize(dimension);
Play.addActionListener(menuhandler);
private class main_menuhandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==Play){
teams Team = new teams();
Team.teams();
disposeMainMenue();
}
if(e.getSource()==Close) {
System.exit(DO_NOTHING_ON_CLOSE);
}
}
}
Anyway, I would like to transfer the Selected value of the Combobox to a method of the other class. I know how I can get the itemvalue of the combobox in the method itself (with getselecteditem) But how can I do that in the ActionPerformed Method as I can't access the combobox in the ActionPerformed method.... I created another ActionListener (comboBox_Listener) but I haven't put any code into it...
Any idea? Thanks a lot in advance
Several issues appear to me:
Your main question:
But how can I do that in the ActionPerformed Method as I can't access the combobox in the ActionPerformed method
Your likely best solution is to change your code and variable declaration placement so that you can access the JComboBox fromt he actionPerformed method. If you're declaring the combobox from within a method or constructor, change this so that it is a proper instance field of the class.
Other problems:
You should not be creating multiple JFrames. If you need a dependent window, then one should be a JDialog. If not, then consider swapping views with a CardLayout.
Learn and follow Java naming conventnions so others can better understand your code. Class names begin with capital letters and methods and variable names don't for instance.
I am not sure why you're doing this: System.exit(DO_NOTHING_ON_CLOSE);. Why pass that constant into the exit method?
Use a constructor for your action listener class:
private class main_menuhandler implements ActionListener {
private JComboBox<String> Team_ComboBox;
public main_menuhandler(JComboBox<String> Team_ComboBox){
this.Team_ComboBox = Team_ComboBox;
}
}
Now you can create the class main_menuhandlervia the constructor and add the combobox to it.
In your Overriden action you have access to it.
Try playing around with this as your code snippet isn't broad enough to actually provide proper code. But this should answer your question
Below program will create 2 simple windows where we can type some text, and it will be shown in both windows' display screen.
I created a Class to generate UI. However, when I use the same class to create 2 objects (typeWriterObj1 & typeWriterObj2) and click on btnSend.
The typed in message are always directed and displayed in the last created window (For example: I type text into Alice's txtMessage and click btnSend, text is shown in Bob's window instead of Alice's).
See below example:
public class TextProgram
{
public static void main(String[] args)
{
TypeWriterUI typeWriterObj1 = new TypeWriterUI();
TypeWriterUI typeWriterObj2 = new TypeWriterUI();
TypeWriterObj1.showGUI("Alice");
TypeWriterObj2.showGUI("Bob");
}
}
class TypeWriterUI extends JPanel
{
static JButton btnSend;
static JTextArea txtDisplay = new JTextArea();
static JTextArea txtMessage = new JTextArea();
//...Codes which add the swing components
//ActionListerner for btnSend which transfer input text from txtMessage to txtDisplay
}
Que: How can this problem be resolved if I were not to use multi-threading?
Undo making the fields static (one instance per class). Both GUIs shared every button instance. That this worked is even a miracle; probably twice assigned a new JButton to the same variable and so on.
The code below shows a problem I'm having with combo actions. The getSelectedItem() is fired multiple times instead of just at selection. Simply loading the frame calls the method 3 times. Each click on the combo box is a call, even if its just for the dropdown and not the actual selection. Clicking inside the editable text area also triggers the getSelectedItem() method. Is there a way to filter this event?, or an alternate way to validate data on the box model level?
public class SSCCE {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
JFrame aframe = new JFrame();
Combo _combo = new Combo();
_combo.addElement("This");
_combo.addElement("That");
JComboBox _box = new JComboBox(new Combo());
_box.setEditable(true);
aframe.add(_box);
aframe.setVisible(true);
}
static class Combo extends DefaultComboBoxModel{
public Combo(){
}
int i = 0;
#Override
public Object getSelectedItem() {
System.out.println("Get selected Item" + i);
i++;
return super.getSelectedItem();
}
}
}
See this tutorial on how to use JComboBox, specifically the section on handling events. You should add an ActionListener to your combobox. It will be triggered when the user actually makes a gesture indicating that their selection is confirmed.
You have look at ItemListener or ActionListener added to the JComboBox
getSelectedItem() indeed fires multiple times, as well as the action event. For an editable combo box the action fires once for comboboxchanged, and once for comboboxedited. I've set up the validation that is not specific to end item in the getSelectedItem, and moved the rest into a filtered action event for comboboxchanged. I've completely ignored comboboxedited event.
Example now I have a main frame contains jtable display all the customer information, and there was a create button to open up a new JFrame that allow user to create new customer. I don't want the user can open more than one create frame. Any swing component or API can do that? or how can disabled the main frame? Something like JDialog.
I think you should use this code for the main jframe when you trying to open new one :
this.setEnabled(false);
I would suggest that you make your new customer dialog a modal JDialog so that you do not allow input from other dialogs/frames in your app while it is visible. Take a look at the modality tutorial for details.
Sorry for the late answer but have you considered the Singleton design pattern? It will return the same instance of a class whenever you want the class. So if the user wants a frame to enter the details, there will only be one frame open (same instance)
It goes something like this:
private static MySingleFrame instance = null; //global var
private MySingleFrame() { } //private constructor
private static MySingleFrame getInstance()
{
if(instance == null)
{
instance = new MySingleFrame();
}
//returns the same instance everytime MySingleFrame.getInstance() is called
return instance;
}
just use firstFrame.setVisible(false) on the first frame. This will make it hidden..
if you want a more general approach you could have a reference to the current displayed frame somewhere and change it when a new frame requests to be shown
JFrame currentFrame;
void showRequest(JFrame frame)
{
currentFrame.setVisible(false);
currentFrame = frame;
currentFrame.setVisible(true);
}
You can use:
private void btn_NewFormActionPerformed(java.awt.event.ActionEvent evt) {
this.hide();
new Frm_NewFormUI().setVisible(true);
}