Found solution
decided it was easier to simply make a method outside of the actionListener called chairPrice which can be incremented by a method called getItemPrice(). This has been used to calculate the total price of items and works 100%
You need to use the Object.equals() method.
#Override
public void actionPerformed(ActionEvent buttonClick)
{
if(buttonClick.getSource().equals(guiButtons[0])) //if user clicks on 'add chair'
{
Chair chair = new Chair();
}
}
Edit in response to the OP's comment
I'm not exactly sure what you're wanting. myChair isn't the name of your chair. It's the name of the variable. It has no effect on Chair at all. If you want to make a new Chair object and have it available for the whole class, you're going to need to either add a new field variable or make a list of Chair.
public class GuiClass extends JPanel implements ActionListener
{
List<Chair> chairs = new ArrayList<Chair>(Arrays.asList(new Chair()));
Desk myDesk = new Desk();
Table myTable = new Table();
#Override
public void actionPerformed(ActionEvent buttonClick)
{
if(buttonClick.getSource().equals(guiButtons[0])) //if user clicks on 'add chair'
{
chairs.add(new Chair());
}
}
}
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.
first of all I will introduce what I am trying to do. This is an assignment in university we are making Hotel booking system with JAVA. To go straight to the point, all I need to know is how to update JList when I press button.
listModel = new DefaultListModel<Hotel>();
bookingList = new JList(listModel);
class MouseAdapterMod extends MouseAdapter {
public void mousePressed(MouseEvent e) {
if(e.getSource() == searchButton){
for(lists.getRoomsList() p : lists.getRoomsList())
{
listModel.addElement(p);
}
bookingList.setModel(listModel);
}
In this GUI class I have instance variable (lists) of Hotel class, in Hotel class there are methods
public ArrayList<Rooms> getRoomsList()
{
return roomsList.getListRooms();
}
public ArrayList<Suite> getSuitesList()
{
return roomsList.getListSuites();
}
this returns whole ArrayList of Room class objects and also ArrayList of Suite class.
QUESTION would be is how to show whole ArrayList of Rooms when I press button, in other words how to update JList which consists of objects, by pressing button?
I hope I explained alright.
Your for-each loop is wrong. Try this and see:
public void mousePressed(MouseEvent e) {
if(e.getSource().equals(searchButton)){
ArrayList<Rooms> rooms = lists.getRoomsList();
for(Rooms r : rooms) {
listModel.addElement(r);
}
bookingList.setModel(listModel);
}
}
This still looks sorta messy to me though. A more appropriate approach would be to set an event handler on the searchButton, to populate the JList when searchButton is clicked.
Also, are Rooms and Suites sub classes of Hotel? If not, you'll have to create listModel like this (for rooms):
listModel = new DefaultListModel<Rooms>();
I'm writing a simple UI just to get the hang of things. I have a tabbed window with two tabs, one has a button that counts up an integer, the other has a text field showing the content of said integer. Or at least that's the plan.
Everything works just fine if I stuff everything into one class. I can access tab 1 from my actionlistener and change the text field in tab 1 from the button press in tab 2. But I don't want my entire program to be in one class, obviously.
And here I have no idea what to do: I need to tell the textfield in the Class Tab1 to change on the button press in the Class Tab2. What's the right thing to do here? My first thought was to hand over an instance of Tab1 in the creation of Tab2, so I could do tab1.changeText(). But that would get messy quickly once I'd get more tabs that interact with each other. So, instead, I want to update the content of the first tab every time it is opened, but I don't know how to do that. And I don't know if that's the right thing to do, either. So, help!
Here's some code. "content" is an instance of Content, a class handling all the logic like adding to the counter.
Main GUI Class:
public class GUI extends JFrame {
//Stuff..
JTabbedPane tabs = new JTabbedPane();
tabs.addTab("One", new Tab1(content));
tabs.addTab("Two", new Tab2(content));
//Stuff..
Tab 1:
public class Tab1 extends JPanel {
public Tab1(Content content) {
JPanel tab1 = new JPanel();
//Stuff..
JTextField tfCount = new JTextField(content.getCounter(), 10);
tab1.add(tfCount);
this.add(tab1);
//Stuff..
Tab 2:
public class Tab2 extends JPanel {
public Tab2(Content content) {
JPanel tab2 = new JPanel();
//Stuff..
JButton btnCount2 = new JButton("Count");
btnCount2.addActionListener(new TestListener(this.content));
tab2.add(btnCount2);
this.add(tab2);
}
private class TestListener implements ActionListener {
Content content;
public TestListener(Content content) {
this.content = content;
}
#Override
public void actionPerformed(ActionEvent e) {
this.content.addToCounter(1);
}
}
Now, if all of that would be in one class (plus subclasses), I could just access tfCount from Tab2 and do tfCount.setText(content.getCounter());. Now tfCount is in a different class, though, and I cannot access it, unless I hand over an instance of Tab1 to Tab2 (like tabs.addTab("Two", new Tab2(content, Tab1);). Couldn't I instead get Tab1 to repaint itself whenever it is opened, like having a method that executes tfCount.setText(content.getCounter()) in Tab1 whenever it is opened, or something along those lines? If so, how do I do that?
With you controls separated in this manner you have a view choices...
You Could...
Share an instance of each "tab" with each of the other tabs, allowing them to either access the others controls or attach listeners across each other. This is very tightly coupled and messy.
The other problem is, does the button really care about the text field or visa versa...
You Could...
Create a simple model that contains the current int value and provides a means to change that value.
The model would have the capacity to fire a ChangeEvent (for example) when the value is changed, which interested parties could listen for and update themselves accordingly.
This decouples the code, reducing the complexity and greatly increasing the flexibility and reuse of various elements of your code.
This is commonly known as an observer pattern and is widely used in Swing.
A possible (listener) example...
For me, I always start with an interface, this describes the absolute minimum requirements that must be meet in order to achieve the required goal. Each tab will want to know the current value, be able to set the next value and listener for changes to the model...
public interface NumberModel {
public int getValue();
public void setValue(int value);
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
}
An abstract implementation deals with the more "common" implementation details, things that a concrete implementation won't want to have to implement, as it's common enough to all implementations. In this case, that would the listener management...
public abstract class AbstractNumberModel implements NumberModel {
private List<ChangeListener> listeners;
public AbstractNumberModel() {
listeners = new ArrayList<>(25);
}
#Override
public void addChangeListener(ChangeListener listener) {
listeners.add(listener);
}
#Override
public void removeChangeListener(ChangeListener listener) {
listeners.remove(listener);
}
protected ChangeListener[] getChangeListeners() {
// FIFO...
List<ChangeListener> copy = new ArrayList<>(listeners);
Collections.reverse(copy);
return copy.toArray(copy.toArray(new ChangeListener[listeners.size()]));
}
protected void fireStateChanged() {
ChangeListener[] listeners = getChangeListeners();
if (listeners != null && listeners.length > 0) {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : listeners) {
listener.stateChanged(evt);
}
}
}
}
And finally, a concrete implementation, which deals with the implementation specific details...
public class DefaultNumberModel extends AbstractNumberModel {
private int value;
public DefaultNumberModel() {
}
public DefaultNumberModel(int value) {
setValue(value);
}
#Override
public int getValue() {
return value;
}
#Override
public void setValue(int num) {
if (num != value) {
value = num;
fireStateChanged();
}
}
}
We could be a slightly more flexible model by doing something like public interface NumberModel<N extends Number> which would allow you define models that could hold Integer, Double, Float and Long for example, but I'll leave that to you.
Each of you tab views will need a setModel(NumberModel) method, so you can pass the model it. In these methods, you will attach a listener to the model and get the current value so that the model and view are in sync.
I have this gui pop up panel and it got things to filled up like packets number, distance etc. Once users fill in the information, he will click ok, the gui will close and my other gui class which has calculation method should receives all data that are filled in earlier gui. How do I store that data? I know I can store in temp file but I don't want to do that. I hope you can enlighten me.
import java.awt.*;
import java.applet.Applet;
class Example extends Applet implements ActionListener
{
TextField txt = new TextField(10);
Button goButton = new Button("Go");
String data = new String ();
public void init ()
{
add(txt);
add(goButton);
goButton.addActionListener(this);
}
public void actionPerformed (ActionEvent e)
{
String cmd = e.getActionCommand();
if (cmd.equals("Go"))
{
// preserve data
data = txt.getText();
repaint();
}
}
}
You should create an intermediate class that represents the data.
After the GUI has been filled in and the submit button clicked, parse the data and fill in the fields in your class.
For example:
public class MyData {
public String Name;
public String Address;
}
Then, fire a method in your calculation method that takes this class as a parameter:
public void Calculate(MyData data) {
...
}
For more advanced handling, look into "interfaces" in Java - that's the standard way this is done.
I'm having a difficults to add rows to a table that located in different class.
Following are the classes structure:
The dashed arrow is the desired relation that I dont manage to have
in the AddPanel class I have a fileds and Addbutton.
when clicking the addButton I first creating an instance of Product (class located in Logic Package). Then I need to add row to the table (Using the TableModel.AddRow method).
Following are the GUI Looks (the focused tab is AddPannel):
I tried different approches but non of them were successed.
My last attempt was to create in the Table class the following method:
public void AddRow(Product p) {
tbmStock.addRow(new Object[] { p.getExternalId(), p.getName(),
p.getAmount(), p.getPriceForMe(), p.getPriceForCustomer() });
}
In addition, in the AddPanel class I tried to add the following method:
private void AddButtonAction() {
btnAddProduct.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
Product p = new Product(txtName.getText(), txtExternalID
.getText(), Integer.parseInt(txtAmount.getText()),
Double.parseDouble(txtPriceForMe.getText()),
Double.parseDouble(txtPriceForCustomer.getText()),
Integer.parseInt(txtFromYear.getText()), Integer
.parseInt(txtToYear.getText()), Integer
.parseInt(txtSupplier.getText()), Integer
.parseInt(txtCarType.getText()));
AddRow(p); //This call doesn't compiles
}
catch (Exception e1){
JOptionPane.showMessageDialog(null,"Error");
}
}
});
}
Any suggestions ? (actually I'm not sure even that my structure is good :S )
Provide a custom event and event listener. If you create a new product fire the event and notify all listeners. The MainPanel (assuming that's where you create the instance of AddPanel), should register a listener. In this listener you then can update the table as the MainPanel has access to the table.
This is also known as the Mediator pattern.
Some pointers:
Create an event class, e.g. ProductCreatedEvent extends EventObject. Pass the Product as an argument to the constructor and make it accessible with a getter.
Create an event listener class: interface ProductCreatedEventListener extends EventListener. Provide a method such as productCreated(ProductCreatedEvent productCreatedEvent).
In the AddPanel add something like:
private final List<ProductCreatedEventListener> productCreatedEventListeners = new ArrayList<>();
...
public void addProductCreatedEventListener(ProductCreatedEventListener productCreatedEventListener){
productCreatedEventListeners.add(productCreatedEventListener);
}
public void removeProductCreatedEventListener(ProductCreatedEventListener productCreatedEventListener){
productCreatedEventListeners.remove(productCreatedEventListener);
}
private void fireProductCreatedEvent(ProductCreatedEvent event){
for (ProductCreatedEventListener productCreatedEventListener : productCreatedEventListeners){
productCreatedEventListener.productCreated(event);
}
}
Replace:
AddRow(p); //This isn't working
with
fireProductCreatedEvent(new ProductCreatedEvent(AddPanel.this, p));