I am a beginner to Java and I have a JComboBox control already on my screen.
In my code I am trying to read data from a file and populate the combo box with it.
I have gone through the documentation and examples from searching here and tried below two methods to perform this action:
I tried to:
jComboBox1.removeAllItems();
jComboBox1.addItem("test string");
and then I tried to do this:
jComboBox1.removeAllItems();
jComboBox1.setModel(new DefaultComboBoxModel(new String[] { "test", "string" }));
I get no errors when I run the program, but nothing happens to the Combo Box data and it just contains the default values of Item 1, Item 2, Item 3, Item 4.
Can someone help me with what I am missing?
Edited - Here is the code for the procedure. This procedure is called from the public static void main(String args[]) procedure which seems to run when the program starts. The stuff being printed to the System output shows up so I know the code block is running, and there are no errors generated.
2nd Edit - I thought the issue was with combobox, but I tried changing label or text field value but they don't work either. I have updated code to show the procedure about it where I am able to update the label and text field, but in the procedure below it doesn't work. I must not be referring to the controls properly for some reason in the procedure I created compared to the one that was system generated?
3rd Edit - Ok more testing and it is the way I am calling the second procedure is where the issue is. If I run the second procedure from the first, everything works fine. I did below to run the procedure when JFrame starts and that is where the issue is. Trying to figure out how to fix that now.
NewJFrame test = new NewJFrame();
test.LoadCmbData();
private void cmdStartActionPerformed(java.awt.event.ActionEvent evt) {
if (cmdStart.getText()=="Start Game")
{
//randVar.nextInt();
//strWord=strWords[Integer.valueOf(cmbRnd.getSelectedItem().toString())];
txtOutput.setText("");
txtOutput.setEnabled(true);
txtInput.setEnabled(true);
cmdInput.setEnabled(true);
cmdStart.setText("End Game");
lblStatus.setText("Enter your first guess and click 'Check'");
intTries=0;
//jComboBox1.addItem("test string");
//lblStatus.setText("Click 'Start Game' button to begin");
}
else
{
cmdStart.setText("Start Game");
txtInput.setText("");
txtInput.setEnabled(false);
cmdInput.setEnabled(false);
//txtOutput.setText("");
txtOutput.setEnabled(false);
lblStatus.setText("Click 'Start Game' button to begin");
}
}
public void LoadCmbData()
{
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current relative path is: " + s);
// Load word choices from file
try
{
File readfile = new File(s + "\\words.txt");
ArrayList linedata = readfile.OpenFile();
System.out.println("ArrayList populated");
// NewJFrame test = new NewJFrame();
// test.cmbRnd.removeAllItems();
// test.cmbRnd.addItem("test");
// test.cmbRnd.setModel(new DefaultComboBoxModel(new String[] { "test", "string", "test", "string", "one" }));
// //test.setModel(new DefaultComboBoxModel(linedata.toArray()));
// test.cmbRnd.updateUI();
// test.cmbRnd.revalidate();
// test.cmbRnd.repaint();
lblStatus.setText("test ");
txtInput.setEnabled(true);
txtInput.setText("test");
jComboBox1.removeAllItems();
jComboBox1.addItem("test string");
jComboBox1.updateUI();
jComboBox1.revalidate();
jComboBox1.repaint();
//NewJFrame test = new NewJFrame();
// test.repaint();
// test.revalidate();
//jComboBox1.removeAllItems();
//jComboBox1.setModel(new DefaultComboBoxModel(new String[] { "test", "string" }));
//jComboBox1.updateUI();
//jComboBox1.revalidate();
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
Thanks!
Figured out what I was doing wrong. Being the total newbie that I am, I was calling that procedure from the "public static void main(String args[])" procedure thinking that is where the loading code goes since it worked when I did some System.out messages.
After backtracking my issue and figuring out above was cause, I now know to put the procedure in the "Constructor" method which I now have learnt about.
I still don't know why it doesn't work from the other location since it obviously runs the procedure, just doesn't update controls. If someone is willing to explain that to me that would be helpful.
Thanks!
Related
I am struggling to fix this for like 2 hours and still nothing really happened. I've tried updating the JLabel with multiple methods like revalidate, paintImmediately, etc, although it didn't change the final result.
public void notificationtos( ) {
jLabel2.setText( "Read our ToS first, please." );
jLabel2.revalidate();
jLabel2.paintImmediately(jLabel2.getVisibleRect());
System.out.println("debug" );
System.out.println( jLabel2.getText() );
}
private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
if( prihvaceniuslovi == false ) {
new notification().notificationtos();
new notification().setVisible(true);
}
}
Also on debugging, here's the output from the code above:
run:
debug
Read our ToS first, please.
BUILD SUCCESSFUL (total time: 3 seconds)
GUI shows up normally, but the string isn't being changed from the one that's been set on initialization of the JLabel.
Instead of this string below that's been shown in photo...
GUI Photo here
this one should've been shown
"Read our ToS first, please."
I would be very grateful if someone could actually help me. Thanks!
EDIT, Here's the solution code, thanks alot #camickr
private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
if( prihvaceniuslovi == false ) {
notification objekt = new notification();
objekt.setVisible(true);
objekt.notificationtos();
}
}
There is no need for repaint() or revalidate() or paintImmediately(). All that is needed is to invoke the setText() method.
If the text doesn't change on the frame then you have two labels:
One that you added to the frame and
another one that is just sitting in memory.
The problem would be the code below:
new notification().notificationtos();
new notification().setVisible(true);
You should NOT keep creating new instances of a component. A component should be created once and then you save a refrence to the variable in your class that that you can make changes to the component in the future.
Read the section from the Swing tutorial on How to Use Text Areas. It shows how you can keep adding text to the same text area. You need to restructure your code to be similar to the demo example.
I'm working on a Plugin for compressing images. Before the "magic happens" the user should decide, if he wants use a method with three or four neighbors.
For this, I created a generic Dialog with a RadioButtonGroup.
This works fine, my question is how do I get the choice of the user? The Method getRadioButton gives a Vector back. But I don’t know how to handle this. My plan was to use the Index of the Button which was choose as a parameter for my main class, but I don’t see a way to manage this.
Have you any idea?
Edit: My Code (without import)
public class FrameDemo_ extends PlugInFrame {
public FrameDemo_ (){
super("FrameDemo");
}
public void run (String arg){
String[] items = {"Option A", "Option B"};
GenericDialog gd = new GenericDialog("FrameDemo settings");
gd.addRadioButtonGroup("Test",items,2,1,"0");
gd.showDialog();
if (gd.wasCanceled()){
IJ.error("PlugIn canceled!");
return;
}
String input;
Vector vec = gd.getRadioButtonGroups();
Object obj = vec.elementAt(0);
input = obj.toString();
this.setSize(250, 250);
this.add(new Label(input, Label.CENTER));
this.setVisible(true);
}
}
My Target is to do something like:
input = obj.Somefunction; // Input contains for exampe "A" for Option A
class RealPlugin (parameter input){
if(input == A) { do something } // Pseudocode...not the real if for a string
else if {input == B) {do something else }
My Problem is, when I convert the Object to String it is:
java.awt.CheckboxGroup[selectedCheckbox=java.awt.Checkbox[checkbox0,0,0,66x23,invalid,label=Option A,state=true}}
I'm sure there is a way for String manipulation, but I don't think this is the proper way to do this. I mean this must be a so typical job (use a radiobuttongroup to get a user choice) that there must be a clever way or a function...
Note: questions like these are usually answered much faster on the ImageJ forum, where more ImageJ experts will read them.
To retrieve the result from a radio button group, use the getNextRadioButton method of GenericDialog. Here's a small Groovy script that can be run directly from the script editor in ImageJ:
import ij.gui.GenericDialog
gd = new GenericDialog("FrameDemo Settings")
items = ["Option A", "Option B"]
gd.addRadioButtonGroup("Test", (String[]) items, 2, 1, "0")
gd.showDialog()
if (gd.wasOKed()) {
answer = gd.getNextRadioButton()
println answer
}
With ImageJ2 (that comes included with the Fiji distribution of ImageJ), it's much easier to get this kind of choice, using SciJava script parameters:
// #String(label="Choice", choices={"Option A", "Option B"}, style="radioButtonVertical") choice
println choice
In Java, the same would look like this:
#Plugin(type = Command.class, menuPath = "Plugins>My New Plugin")
public class MyNewPlugin implements Command {
#Parameter (label="Choice", choices={"Option A", "Option B"}, style="radioButtonVertical")
private String choice;
// your code here
}
For a full example, see https://github.com/imagej/example-imagej-command
I've been having a problem with my program that has been driving me crazy and I cannot understand why this is happening. I have a GUI that when the "Add" button is pressed, a new system listing appears (Which is a class called SystemPanel that extends JPanel and cotains system details, which is created and then put into the Frame's main panel.)
To put it shortly, when I try to add a new SystemPanel, it does not appear for whatever reason. I have code using JSch that connects to the system and verifies whether its processes are online or not, but the line of code that does this is after the creation of the SystemPanel. It is only after the code for testing the processes of the system are executed that the SystemPanel becomes visible, and I can't understand why this is the case. Here is the code for adding a new SystemPanel:
public void actionPerformed(ActionEvent e) {
//If the "Add" button is pressed
if (e.getActionCommand() == "Add") {
PopupWindow popup = new PopupWindow(this);
popup.setVisible(true);
String[] results = popup.getResults();
if (results[0] != null && results[1] != null && results[2] != null && results[3] != null && results[4] != null) {
SystemPanel newSystem = new SystemPanel(this, results[0], results[1], results[2], results[3], results[4]);
systemsPanel.add(newSystem);
revalidate();
systemsList.add(newSystem);
System.out.println("Did the stuff");
boolean[] status = SystemChecker.checkOnline(results[0], results[1], results[2], results[3]);
}
}
}
The PopupWindow is a custom JDialog that allows the user to enter the required information which is returned in a String array and is used to create a new SystemPanel. The checkOnline function grabs the user's inputs and uses them to connect to the system and determine whether the processes are working or not, and returns the results into a boolean array, true for working, false for not.
What's even weirder is that I have another part of my program that reads from an .ini file to obtain existing systems and then creates SystemPanels based on the data that it reads. Through this method, the SystemPanels are added the way I want and work perfectly for some reason, even though the code for adding the panels is hardly any different. Code:
for (int i = 0; i < systems.size(); i++) {
SystemPanel newSystem = new SystemPanel(this, systems.get(i)[0], systems.get(i)[1], systems.get(i)[2], systems.get(i)[3], systems.get(i)[4]);
systemsPanel.add(newSystem);
revalidate();
systemsList.add(newSystem);
}
for (int i = 0; i < lineNum; i++) {
boolean[] status = SystemChecker.checkOnline(systems.get(i)[0], systems.get(i)[1], systems.get(i)[2], systems.get(i)[3]);
systemsList.get(i).updateIcons(status);
}
This code grabs the details from the file and then makes the SystemPanels based on those details. Here, all of the SystemPanels are added and show up before the connection is tested, which is what I want to happen when I add one normally.
Why is it that the SystemPanel doesn't appear until the connection is tested, even though the code for displaying the SystemPanel is executed before the connection test? Any help would be greatly appreciated, thanks.
Try it of the current event queue handling, on which actionPerformed is done.
public void actionPerformed(ActionEvent e) {
EventQueue.invokeLater(() -> { ... your code here ... });
}
Also you cannot add the same component to two parents, every component object has a single parent (container).
(Java 8 notation)
So I have this project,
the source code is here.
When you run the project and goto Processing, there is a jcombobox there that is suppose to have an addActionListener.
p_customer_list = new JComboBox<>(customers_name);
pp_customer_list.setPreferredSize(new Dimension(360, 35));
panel_processing_header.add(pp_customer_list);
//pp_customer_list.addActionListener(this);
pp_customer_list.addActionListener (new ActionListener () {
public void actionPerformed(ActionEvent e) {
JComboBox tmpBox = (JComboBox) e.getSource();
int selected = tmpBox.getSelectedIndex();
pp_refresh_data(selected);
}
});
This is what I have so far, its suppose to find the selected index when the value of the combobox changes and pass it to pp_refresh_data() but for some reason it does not run (I tried putting a JOptionPane to see when the code is executed, and its only executed once when the program runs.)
Hard to tell from just a partial code snippet, but do you have 2 combos, one named "p_customer_list" and another named "pp_customer_list"?
This could be your problem. You may be adding the listener to the wrong combo, or you may be adding the wrong combo to your panel, or maybe you don't need two, or maybe...
Again, it's hard to tell from just a snippet.
I've been looking all over, and i cant find anyone who can solve this problem. I'm making a game, and in that game, i have editable controls. the controls window is a seperate JFrame, and when i click the confirm button, it is supposed to write the items in the JTextFields (holding the controls) to a file. but that wasnt working, so instead i have it print the arraylist that holds the values. here is the code:
public void writeControls() {
ArrayList<String> al = new ArrayList<String>();
al.add(up.getText());
al.add(down.getText());
al.add(left.getText());
al.add(right.getText());
al.add(jump.getText());
al.add(duck.getText());
al.add(attack.getText());
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
System.exit(0);
}
the problem is this: if i change the final JTextField attack or any other one for that matter, and click submit, the system prints out the default controls. for example, if the JTextFields have the values w,a,s,d,r,t,q and i change the value q to i, it prints out q. what am i doing wrong? thanks in advance!
EDIT 1:
code for the textfields, and the FILES.... is simply a string stored in a different class. the class setText() is below the textfields.
up = new JTextField(setText(FILES.controlsFileFinalDir, 1));
down = new JTextField(setText(FILES.controlsFileFinalDir, 2));
left = new JTextField(setText(FILES.controlsFileFinalDir, 3));
right = new JTextField(setText(FILES.controlsFileFinalDir, 4));
jump = new JTextField(setText(FILES.controlsFileFinalDir, 5));
duck = new JTextField(setText(FILES.controlsFileFinalDir, 6));
attack = new JTextField(setText(FILES.controlsFileFinalDir, 7));
public String setText(String fileDir, int lineNum) {
String txt = "";
txt = io.readSpecificLine(fileDir, lineNum);
txt = switchCase(txt);
return txt;
}
switchcase() is only taking what you have written in the text file that these are getting the values from, and translating them. so if the value is 0, it is turned into Space, etc. io.readSpecificLine(); is only to get the line of text from the file. does this help?
EDIT 2:
i just was dinking around and found out that if i set the JTextField text by using setText(""); then use getText(); it works. so the problem is that when i change it manually, and use getText(); it wont work. Why?
To update the text to a currently existing JTextField, I would establish the JTextField as a class variable, and create a setter/getter method to adjust it (which I'm assuming you're doing).
According to your methods, you would use something like:
up.setText(setText(FILES.controlsFileFinalDir, 7));
Edit: **The first setText is the JTextField.setText, the second setText is your public method you posted. I'm assuming your second getText() isn't working because you're probably not setting the text correctly.
Without seeing more code, I can't really give a better guess.
The main possibilities:
(1) The text fields have their editable property set to false.
(2) You are creating multiple copies of the JTextFields, then editing a new one on the screen, but referring to the old one when you get the value.
(3) You have a ValueChanged or LostFocus event handler that is resetting the text fields to their defaults
(4) It is actually JFormattedTextField not a JTextField
If I was you, I would try to debug the programm. You will probably do some Mistake in your code, you won't be able to see, by just checking the code.
For example in which order do you call the functions and so on, maybe you have a fault here, or maybe you have several threads, so you try to read the Textfields without even set them and so on ... It's hard to say without reviewing the whole Code.
So if you use eclipse you can follow this link for an explanation on how to debug: http://www.vogella.com/articles/EclipseDebugging/article.html
Netbeans or any other IDE should support debugging as well.
This may seem like a strange thing to suggest, but I think this is an issue with pointers. If you create a new string before passing it in, JTextField will be able to change it internally and return what you expect when asked for the modified value.
down = new JTextField("" + setText(FILES.controlsFileFinalDir, 2));
// or
down = new JTextField(new String(setText(FILES.controlsFileFinalDir, 2)));
You might want to try the following:
create a class Test.java
import java.util.ArrayList;
import javax.swing.JTextField;
public class Test implements Runnable {
private ArrayList<JTextField> textFields = null;
private ArrayList<String> stringList = null;
public Test(ArrayList<JTextField> textFields, ArrayList<String> stringList) {
this.textFields = textFields;
this.stringList = stringList;
}
#Override
public void run() {
for ( JTextField textField : this.textFields )
this.stringList.add( textField.getText() );
}
}
and then, at the place where you use the "getText() method .. "
do the following...
ArrayList<JTextField> textFields = new ArrayList<JTextField>();
// add all the JTextField to textFields
ArrayList<String> stringList = new ArrayList<String>();
Test test = new Test( textFields, stringList );
SwingUtilities.invokeLater( test );
// check if the stringList is populated.
If this work, then what I believe is that, for some reason, the JTextField hasn't finished
"setting" the text, and before it finishes your getText() was called. I've had similar problems before, and this solved my problem that time, but still, this might not be the perfect solution.
First, you should change your "setText()" method name to something like "getTextFromFile()" it would be more readable
Then, if you are setting and reading the new text in different threads, my bet is that the setText() is taking long to return, because it is accessing the file system, while the method that read the values run instantly
I would try to do run a little test:
public void test(){ // must be run after the JTextFields be initialized
up.setText("TEST")
System.out.println(up.getText());
up.setText(setText(FILES.controlsFileFinalDir, 1));
System.out.println(up.getText());
}
If the test() prints the correct values, then we can assume that if you set and read the new value in the same thread it works fine
The other test I would do is:
public void testThread(){
new Thread(){
public void run(){
while(true){
if(up!=null){
System.out.println(up.getText());
}
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
}
}.start();
}
It will print the value of up each 1 second, so that you can see if after some time you get the new value. If it does, then the answer is: Your setText() is taking long to run and you are reading the value before the new value is set
SOLUTION
none of the above answers were working for me, so i finally decided to just start over with that class. the few things i changed were the way i made the JTextFields. I made them as an array instead of individual objects. Second is the way i put what they say. When i initialized them, i was unable to get them to create WITH the text in the parameters. so i had to do that seperately. i changed some of the method names so as to reduce future confusion, and it worked! so im not sure what was up with that, maybe it was the way i did it, maybe just a fluke. it happens sometimes, so im sorry for the delay and waste of your time! thanks for all the answers anyway!
Try this:
textbox.setText(setFile(args)); // your function for set file