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.
Related
To begin with I'm in this just a few days so I am sorry if this is a silly question, I did my search but I didn't find what I was looking for.
Simply said, I've got a class like this:
public class logout extends JButton {
private static final long serialVersionUID = -4813329911065574369L;
public static JButton logout = new JButton("Izloguj se");
public logout()
{
//parameters like font, foreground etc
}
And when I try to call it in another class, like this:
ctrl.add(prikaz.logout.logout);
I get an old plain button with text I defined in class but none of the parameters I defined for it.
I know I can add the button with its settings if I do something like:
JPanel lgtBtn = new logout();
But I would like to do it directly with add.
You define the logout button with:
public static JButton logout = new JButton("Izloguj se");
This creates a new JButton with the specified text. But then the class you are in also extends JButton, and it is set up in the constructor. So you have two JButtons, but you only ever reference the one that is not set up. I would just get rid of the line of code above, and reference the button as prikaz.logout (not prikaz.logout.logout).
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.
I have a class "MainFrame1" that extends a JFrame and also another class that is a file chooser. Whenever I press one of the JMenuItems in MainFrame1 class, I want the file chooser to open up and load up the text of the chosen file on a JTextArea that was created in MainFrame1 class. This works perfectly fine as I created a separate class implementing an ActionListener. Now my problem is that when I press another JMenuItem I want to do something else to the text in the JTextArea. I have implemented another ActionListener for that in a different class but the problem is that the JTextArea seems to be empty when I do that although I can see the text in there. Thanks in advance.
This is how I have created the JTextArea in the MainFrame1:
showAction = new JTextArea(10,10);
showAction.setEditable(false);
showAction.setFont(new Font("Arial", Font.BOLD, 12));
add(showAction, BorderLayout.NORTH);
And this is my second ActionListener class (also, whenever the text of a file is printed in the JTextArea, the text "loaded up." will also be printed) and I always get the else branch.
public class TransformController implements ActionListener{
MainFrame1 mf;
public TransformController(MainFrame1 mf) {
this.mf = mf;
}
#Override
public void actionPerformed(ActionEvent e) {
String text = mf.showAction.getDocument().toString();
if(text.contains("loaded up.")) {
char[] charText = text.toCharArray();
Parser parser1 = new Parser(charText);
parser1.packageVisitor();
}
else {
System.out.println("Load up a Java file first!");
}
}
}
This seems to be mostly a debugging question: First, find out what's in showAction.getDocument() to see if your menu item just isn't loading it right. Then check (with an IDE or via toString()) that mf.showAction really is the same object in the two cases.
Structurally, there's nothing in Java that prevents you from having a reference to the same JTextArea in two parts of the code, and reading the text out of it for different purposes.
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 usually write the code in C#, and I even have the application finished in C#, but I need to port it to Java.
Just started out today, never really used Java before.
The problem is quite strange because I do not get any error it just does not update, here's the code:
public void setInfoStrip(String infoStrip) {
InfoStrip.setText(infoStrip);
}
The above is a Setter that should update the JTextField (and it does if I update it using the ActionListener for a button), but it does not update the text when I call it in a class or even in the main(String[] args) entry point of application using this code:
mainGUI GUI = new mainGUI();
GUI.setInfoStrip("test");
or this code:
new mainGUI().setInfoStrip("test");
My guess is that it does nothing becuase I call it from a static class
public static void main(String[] args)
But even if I create a new class that's not static and reference it from the public staitc void main(String[] args) then put either
mainGUI GUI = new mainGUI();
GUI.setInfoStrip("test");
or
new mainGUI().setInfoStrip("test");
It the newly created class, which I call by
new ImGoingToCry().Alot();
It still does nothing.
I'm confused as hell, I even read some problems connected with this on google but they were all solved by this:
mainGUI GUI = new mainGUI();
GUI.setInfoStrip("test");
Here's the MVCE that some of you requested:
public class mainGUI {
// GUI Elements
private JPanel WorkSpace;
private JTabbedPane tabbedPane1;
private JList DetectedProfiles;
private JButton StartGame;
private JTextField CurProf;
private JButton BackupProfiles;
private JButton SearchSaves;
private JButton RetrieveProfiles;
private JTextField InfoStrip;
private JLabel ProfileSize;
/**
* Getter and Setter functions
*/
public void setInfoStrip(String infoStrip) {
InfoStrip.setText(infoStrip);
}
// Initialize the main application GUI and set it's properties
public static void main(String[] args) {
JFrame mainGUIFrame = new JFrame("The Witcher 3 Save Manager | " + " ver. " + GlobalVariables.appversion);
mainGUIFrame.setContentPane(new mainGUI().WorkSpace);
mainGUIFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainGUIFrame.setLocationRelativeTo(null);
mainGUIFrame.setPreferredSize(new Dimension(420, 370));
mainGUIFrame.setResizable(false);
mainGUIFrame.pack();
mainGUIFrame.setVisible(true);
new mainGUI().run();
}
public void run() {
/**
* Initialize the core application functions
*/
// Load the application settings
GlobalVariables.Settings();
// Initialize the app components
GlobalVariables.Initialize();
// Pass the value to setter
new mainGUI().setInfoStrip("test"); // This should change the text but it does nothing there's not even an error
}
}
May be this will be of help. From javadocs for JTextComponent, from which JTextField inherits setText() method:
setText
Sets the text of this TextComponent to the specified text. If the text is null or empty, has the effect of simply deleting the old text. When text has been inserted, the resulting caret location is determined by the implementation of the caret class.
Note that text is not a bound property, so no PropertyChangeEvent is fired when it changes. To listen for changes to the text, use DocumentListener.
In case you wonder what a BoundProperty is:
A bound property notifies listeners when its value changes. This has
two implications:
The bean class includes addPropertyChangeListener() and
removePropertyChangeListener() methods for managing the bean's
listeners.
When a bound property is changed, the bean sends a
PropertyChangeEvent to its registered listeners. PropertyChangeEvent
and PropertyChangeListener live in the java.beans package.
The java.beans package also includes a class, PropertyChangeSupport,
that takes care of most of the work of bound properties. This handy
class keeps track of property listeners and includes a convenience
method that fires property change events to all registered listeners.
P.S.: as the OP has not given any mcve, this sounds relevant. But, I strongly feel the case is going to be otherwise once we see the OP's code.