ImageJ: Get specific Radiobox - java

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

Related

Issue with adding items to JComboBox in Java

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!

Why won't my Export button display the output from my fields

New to asking questions here on stack overflow. I have a program that has me stumped. I have been able to get it to work but just not in the manner I would prefer and I was wondering if some of you could take a look at it and help me figure out what I am doing wrong. Please see below:
For the beginning, the program doesnt compile in class Output at
String ageStr = Input.getAge().toString();
int ageInt = Integer.parseInt(ageStr);
because getAge() returns the address, not the Text of JTextField. Integer can't parse that, as it inhabits not only integers.
And so does all your static getters only return not intended data.
Try to change those in class Input after this sample:
public static String getAge() {
return age.getText();
}
and don't forget to add the outputPanel in class Output
add(outputPanel, BorderLayout.CENTER);
Additionally,
make those methods non-static as stated by others
separate / encapsulate code into fitting methods and improve your API
keep an overall persistent code appearance.
One option is to define an object variable and change your Output-Constructor:
Input input; // keeps a ref to input
public Output(Input input) {
super("Output", 300, 300);
this.input = input;
String ageStr = input.getAge();
...
And the call to:
public void actionPerformed(ActionEvent e){
output = new Output(Input.this);
output.display();
...
Hope it helps you.
Ok here is what I changed, like I said I'm still getting an error. So far all I have tried to fix is the code associated with the age. I will work the rest when i figure out how to make this work. See new code below. I can get it to work if I leave everything static but I know that's not the appropriate method. Tried to fix the formatting as well.

Parsing a string to specific unknown word for referencing

I have a map that I am referencing within my JFrame in a JList/ScrollPane object so it displays like this:
tongs ... 4.99
oven mitt ... 9.99
and so on. I want to use the users selection to populate a textbox in another form. I have this working just fine, however it currently displays the whole string with the ... [price]. I'd like to only display the object.
I've thought about using the .split method, but I'm not sure if that's correct. Any ideas to help me out here?
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(view.getSubmit())) {
dialog.setObject(view.getSelection()); // This prints the whole string as shown above
dialog.setVisible(true);
}
...
}
setObject() goes to a method tied to a textbox. Instead of displaying 'oven mitt ... 9.99' I'd like it to only say 'oven mitt'. The hard part is that the number of words vary, so I cannot just say take substring xyz.
EDIT: I got it using the following code.
if(e.getSource().equals(view.getSubmit())) { // Launch kiosk
String search, val = null;
search = view.getSelection();
for (myEnum d : myEnum.values()) {
if (search.contains(d.getLocation())) {
val = d.getLocation();
}
}
dialog.setDestination(val);
dialog.setVisible(true);
}

Prepend beginning to object name and set text in java

I'm trying to pick up java quickly and looking for a way to set the text of a number of labels in my java app.
What I have is a java app that starts\stops\checks status of windows services. I have a method, which is passed an array of these service names and each of these services has a corresponding label that contains it's status. For example, DummyService1 is contained in the array and there is a label called txt_DummyService1. My method (short version) does the following
public static void Checker(String Array[])
{
//check status of DummyService1
"txt_"+DummyService.Text = "started";
}
I realize that this isn't the way that you do this, but could anybody help me out with the best way to do this?
There's no way to generate a "variable" name from a String in this manner. Yes, you might use reflection, but that already rasies questions about the quality of the design.
Instead. Place each label into a Map keyed by it's name.
private Map<String, JLabel> labelLookup = new HashMap<>(25); // Instance variable.
In you constructor (or where ever you build your UI), add each label to the Map.
/* Other UI code */
labelLookup.put("DummyService1", txt_DummyService1);
Now, when you need to do you changes, simply look up the label by it's name
// You had better have a VERY good reason for making this static...
public void checker(String services[])
{
for (String service : services) {
JLabel label = labelLookup.get(service);
if (label != null) {
label.setText("Started");
}
}
}
For example...
Actually I was looking for something more like the following
public static void Checker()
{
try
{
Object Instance = getClass().getDeclaredField("txt_DummyService").get(this);
Method m = Instance.getClass().getMethod("setText",String.class);
m.invoke(Instance,"started");
}
catch(Exception e)
{
//exception handling
}
}
You cannot manipulate variable names at runtime since these are only available to the compiler. One solution to your problem is to keep a Map<String, JLabel> (assuming you are using JLabel and not some other component) to associate a name with each JLabel. I'm sure there are several other possible solutions depending on the exact design of your code.

JTextField getText() not working

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

Categories