JCombo + override toString - java

Alright, I am working on a rather large program.
I will try to put in only what you need.
So right now, the comboBox is filling (with the override toString), and the first item is selected.
When I choose different parameters and force the contents of the comboBox to change, the new list is put into the comboBox and the first item is selected again.
I can see the update, so I know it is filling properly.
The problem is that when I select anything in the comboBox, nothing happens.
The first item remains selected, none of my System.out.println lines are printing, so nothing is being executed.
When I remove my override toString, everything works as intended.
The strange part, past that, is when having this override toString removed, it falls back on the parent class who has an override toString.
What is going on?
To my understanding the toString literally changes what is displayed, it does not change the data.
I am adding the objects to the comboBox, but displaying a bit of the information.
public class Belt extends Part{
//variable initialization and methods
#override
public String toString(){
String display = this.getCode() + " - " + this.color;
return display;
}
public final class Something implements ActionListener{
//variable initialization and methods
//there are several methods that call the fillBeltCombo()
GridBagConstraints c = new GridBagConstraints();
private void pad(GridBagConstraints c){
c.anchor = GridBagConstraints.NORTHWEST;
c.weightx = 1;
c.insets.left = 10;
c.insets.right = 10;
c.insets.top = 5;
c.insets.bottom = 5;
}
beltCombo = new JComboBox();
beltCombo.setVisible(true);
c.gridwidth = 2;
c.gridx = 4;
c.gridy = 9;
beltCombo.addActionListener((ActionEvent eventBelt) -> {
JComboBox beltCodeCombo1 = (JComboBox) eventBelt.getSource();
if(beltCombo.getItemCount()>0){
currentProduct.setBelt((Belt)beltCodeCombo1.getSelectedItem());
}else{/*do nothing*/}
});
pane.add(beltCombo, c);
public static void fillBeltCombo(ArrayList<Belt> list){
beltCombo.removeAllItems();
int size = list.size();
for(int x=0; x<size; x++){
beltCombo.addItem(list.get(x));
}
}
}

So taking the advice of markspace, I created a MCVE (the best I could while maintaining what my program was doing). Everything down there is done in my real program, although more complicated. I am not sure yet what my program is doing wrong, however I did find out that what I am trying to do is possible, I am able to select an item from the second comboBox while using an Override toString in the subclass. Now I just have to track the problem down in the actual code...
package minitest;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MainClass {
JFrame frame;
JPanel pane;
JLabel label1, label2;
JComboBox comboA, comboB;
ArrayList<Parent> parents = new ArrayList<>();
ArrayList<Grandchild> grandkids = new ArrayList<>();
Parent parent1 = new Parent(1);
Parent parent2 = new Parent(2);
Grandchild grandkid1 = new Grandchild(1,1,"oneone");
Grandchild grandkid2 = new Grandchild(1,2,"onetwo");
Grandchild grandkid3 = new Grandchild(2,1,"twoone");
Grandchild grandkid4 = new Grandchild(2,2,"twotwo");
public class Parent{
protected int num;
public Parent(int num){
this.num = num;
}
#Override public String toString(){
return String.valueOf(num);
}
}
public class Child extends Parent{
private double dbl;
public Child(int num, double dbl){
super(num);
this.dbl = dbl;
}
}
public class Grandchild extends Child{
private String str;
public Grandchild(int num, double dbl, String str){
super(num, dbl);
this.str = str;
}
#Override public String toString(){
return this.num + " - " + this.str;
}
}
//Fill passed combo with each item from passed ArrayList
public void fillCombo(ArrayList list, JComboBox target){
target.removeAllItems();
int size = list.size();
for(int x = 0; x < size; x++){
target.addItem(list.get(x));
}
}
//remove all items from combobox except selected item
public void comboUpdate(JComboBox combo){
if(combo.getSelectedItem()==null){
/*donothing*/
}else{
int size = (combo.getItemCount()-1);
System.out.println("size: "+size);
for (int x=size; x>=0; x--) {
if(combo.getSelectedItem().equals(combo.getItemAt(x))){
/*donothing*/
System.out.println(combo.getSelectedItem()+" is selected");
}else{
System.out.println(combo.getItemAt(x)+" is now removed");
combo.removeItemAt(x);
}
}
}
}
//Add each item from passed ArrayList if not equal to the selected item
public void removeDuplicate(JComboBox combo, ArrayList array){
System.out.println("removeDuplicate: "+array);
if(combo.getSelectedItem()==null){
System.out.println("combo.getSelectedItem==null");
fillCombo(array, combo);
}else{
boolean validChoice = false;
int arraySize = array.size();
for(int x = 0; x < arraySize; x++){
if(combo.getSelectedItem().equals(array.get(x))){
System.out.println(combo.getSelectedItem()+" == "+array.get(x));
validChoice = true;
}else{
System.out.println(combo.getSelectedItem()+" != "+array.get(x));
combo.addItem(array.get(x));
}
}
if(validChoice == false){
System.out.println("removeItemAt(0)");
combo.removeItemAt(0);
}
}
}
//fill comboB with grandchild objects whos int match the selected partent objects int
public void fillComboB(){
System.out.println("grandkids: "+grandkids);
ArrayList<Grandchild> temp = copyArrayList(grandkids);
System.out.println("temp: "+temp);
comboUpdate(comboB);
int size = (temp.size()-1);
for(int x=size; x>=0; x--){
if(temp.get(x).num==((Parent)comboA.getSelectedItem()).num){
/*donothing*/
System.out.println("donothing: temp.get("+x+")="+temp.get(x));
}else{
System.out.println("temp.remove("+x+")="+temp.get(x));
temp.remove(x);
}
}
removeDuplicate(comboB, temp);
}
public ArrayList copyArrayList(ArrayList list){
ArrayList<Object> temp = new ArrayList<>();
int size = list.size();
for(int x=0; x<size; x++){
temp.add(list.get(x));
}
return temp;
}
public MainClass(){
parents.add(parent1);
parents.add(parent2);
grandkids.add(grandkid1);
grandkids.add(grandkid2);
grandkids.add(grandkid3);
grandkids.add(grandkid4);
frame = new JFrame("frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pane = new JPanel();
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
comboA = new JComboBox();
fillCombo(parents, comboA);
c.gridx = 0;
c.gridy = 0;
comboA.addActionListener((ActionEvent eventComboA) -> {
System.out.println("eventComboA");
JComboBox comboA1 = (JComboBox) eventComboA.getSource();
if(comboA.getItemCount()>0){
System.out.println("comboA.getItemCount>0: "+(Parent)comboA1.getSelectedItem());
fillComboB();
}
});
pane.add(comboA, c);
comboB = new JComboBox();
c.gridx = 0;
c.gridy = 1;
comboB.addActionListener((ActionEvent eventComboB) -> {
System.out.println("eventComboB");
JComboBox comboB1 = (JComboBox) eventComboB.getSource();
if(comboB.getItemCount()>0){
System.out.println("comboB.getItemCount>0: "+(Grandchild)comboB1.getSelectedItem());
}
});
pane.add(comboB, c);
frame.setContentPane(pane);
frame.setSize(150,150);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static void runGUI(){
JFrame.setDefaultLookAndFeelDecorated(false);
MainClass create = new MainClass();
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(() -> {
runGUI();
});
}
}

Aright, so based on yesterdays successful creation (which I was frustrated by) I continued to fill in the skeleton until it broke again.
- Adjusted classes to reflect the actual types of data that I was dealing with.
- Added my override equals method <-------problem
What happened was that when I originally created the equals override, all of the toStrings were the same, and that was displayed in the comboBox.
So the equals override looked like
#Override public boolean equals(Object other){
if (other == null) return false;
return (String.valueOf(other)).equals(this.description);
}
The problem with this, was that when I was asked to change what was displayed in the comboBox, I did not realize that the comboBox seems to use that equals check. The new other Object was
this.getCode() + " - " + this.color;
and it was being compared to num, which returned false.
Now correct me if I am wrong, but the moral of the story seems to be: JComboBox will not let you select something from the list that does not equal something on the list. So because my equals override changed how the objects were compared:
string value of object, compared to string variable of the object-
the same object was not equaling itself.
The adjusted code:
#Override public boolean equals(Object other){
if (other == null) return false;
return ((Parent)other).description.equals(this.description);
}

Related

In Java how would I combine a grid of buttons with a grid of integers to create a minesweeper board?

So far all I have managed to do is combine my two files into one file that creates a GUI with the grid of buttons and runs an instance of minesweeper separately. I need the values from the grid of integers to reflect onto the grid of buttons so that after I click a button it reveals the integer underneath. Any help would be much appreciated.
import javax.swing.*;
import java.awt.event.*;
import java.awt.GridLayout;
import java.awt.Component;
import java.awt.Label;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JOptionPane;
public class Minesweeper extends JFrame implements MouseListener
{
private JButton [][] gridz;
private int [][] g;
private int max;
public Minesweeper()
{
gridz= new JButton [10][10];
builder();
g=new int[10][10];
setRandom(10);
}
public void setRandom(int max)
{
int z=0;
while(z<max)
{
int r=(int)(Math.random()*g.length);
int c=(int)(Math.random()*g[r].length);
if(g[r][c]==0)
{
g[r][c]=-1;
z++;
}
}
}
public int count(int r, int c)
{
int x=0;
if((r-1)>=0 && (c-1)>=0 && (r-1)<g.length && (c-1)<g.length && g[r-1][c-1]==-1)
{
x++;
}
if((r-1)>=0 && (r-1)<g.length && g[r-1][c]==-1)
{
x++;
}
if((r-1)>=0 && (c+1)>=0 && (r-1)<g.length && (c+1)<g.length && g[r-1][c+1]==-1)
{
x++;
}
if((c-1)>=0 && (c-1)<g.length && g[r][c-1]==-1)
{
x++;
}
if((c+1)>=0 && (c+1)<g.length && g[r][c+1]==-1)
{
x++;
}
if((r+1)>=0 && (c-1)>=0 && (r+1)<g.length && (c-1)<g.length && g[r+1][c-1]==-1)
{
x++;
}
if((r+1)>=0 && (r+1)<g.length && g[r+1][c]==-1)
{
x++;
}
if((r+1)>=0 && (c+1)>=0 && (r+1)<g.length && (c+1)<g.length && g[r+1][c+1]==-1)
{
x++;
}
return x;
}
public void setCounts()
{
for(int r=0; r<g.length; r++)
{
for(int c=0; c<g[r].length; c++)
{
if(g[r][c]==0)
{
g[r][c]=count(r,c);
}
String formatted = String.format("%2d", g[r][c]);
System.out.print(formatted + " ");
}
System.out.println();
}
}
public void builder()
{
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(10, 10));
for(int r=0; r<gridz.length; r++)
{
for(int c=0; c<gridz[r].length; c++)
{
gridz[r][c]=new JButton("*");
gridz[r][c].setActionCommand(r+":"+c);
gridz[r][c].addMouseListener(this);
getContentPane().add(gridz[r][c]);
}
}
setVisible(true);
}
public void mousePressed(MouseEvent e)
{
Component c = e.getComponent();
JButton b = (JButton)c;
System.out.println(b.getActionCommand());
String s=b.getActionCommand();
int f=s.indexOf(':');
if(f>=0)
{
String row=s.substring(0, f);
String col=s.substring(f+1);
String text=row+ '!' +col;
b.setText(text);
}
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
public static void main(String[] args)
{
Minesweeper a = new Minesweeper();
a.setCounts();
//JOptionPane.showMessageDialog(null, "BOOM");
}
}
One of the (many) things you want to do, is decouple your code. This means that the "logic" for the "game" should be independent of the "view", meaning that you can easily change the logic without adversely effecting the view.
This is where things like model-view-controller and single responsibility concepts come into play.
What you should (try) and do is start by describing the "data" or "model". What properties does it have and what functionality can be executed by other parties.
Since the models state could change, independently, you'll also need some way to notify interested parties, this is where an observer is helpful.
For example, a model for the game might be represented like...
public interface MineSweeperModel {
public interface Observer {
public void cellValueDidChange(MineSweeperModel model, int col, int row, int value);
}
public int getRows();
public int getColumns();
public int getValueAt(int col, int row);
public void expose(int col, int row);
public void setObserver(Observer observer);
}
Now, that's cool and everything, but what we need is some kind of implementation, which might look something like...
public class DefaultMineSweeperModel implements MineSweeperModel {
private int rows;
private int cols;
private int[][] bombsMap;
private int[][] visibleState;
private Observer observer;
public DefaultMineSweeperModel(int rows, int cols, int maxBombs) {
this.rows = rows;
this.cols = cols;
bombsMap = new int[cols][rows];
visibleState = new int[cols][rows];
Random rnd = new Random();
int count = 0;
while (count < maxBombs) {
int row = rnd.nextInt(rows);
int col = rnd.nextInt(cols);
if (bombsMap[col][row] == 0) {
bombsMap[col][row] = -1;
count++;
}
}
}
#Override
public void setObserver(Observer observer) {
this.observer = observer;
}
#Override
public int getRows() {
return rows;
}
#Override
public int getColumns() {
return cols;
}
#Override
public int getValueAt(int col, int row) {
return visibleState[col][row];
}
#Override
public void expose(int col, int row) {
if (visibleState[col][row] == 0 && bombsMap[col][row] == -1) {
// You've found a mine, might want to do something about it...
visibleState[col][row] = -1;
fireCellValueDidChange(col, row, -1);
} else if (visibleState[col][row] == 0) {
// Empty cell
visibleState[col][row] = 1;
fireCellValueDidChange(col, row, 1);
}
}
protected void fireCellValueDidChange(int col, int row, int value) {
if (observer == null) {
return;
}
observer.cellValueDidChange(this, col, row, value);
}
}
Now, we could just as easily create a "easy", "hard" and "you're going to die" implementations and seed the properties internally, but this basic implementation provides us with enough capacity to configure it.
But why (use a interface)? One of the principles of OO is "information hiding", which is supported by the concept of Polymorphism.
This means we can create any kind of model, with any kind of internal logic, but any one wanting to make use of the model, can easily do so by simply accepting a instance of the interface.
Now, the UI. This is basically responsible for providing a visual representation of the state of the model.
public class MineSweeperPane extends JPanel {
private JButton[] buttons;
private MineSweeperModel model;
public MineSweeperPane(MineSweeperModel model) {
this.model = model;
model.setObserver(new MineSweeperModel.Observer() {
#Override
public void cellValueDidChange(MineSweeperModel model, int col, int row, int value) {
int index = (model.getRows() * row) + col;
if (index >= buttons.length) {
System.err.println("No view for cell # " + col + "x" + row);
return;
}
buttons[index].setText(Integer.toString(value));
}
});
// You should be using ActionListener
MouseListener mouseListener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
JComponent source = (JComponent) e.getComponent();
// Here's something they won't teach you...
GridBagConstraints gbc = ((GridBagLayout)getLayout()).getConstraints(source);
System.out.println(gbc.gridx + "x" + gbc.gridy);
// Use class based Integer so we don't get NullPointerException
Integer row = (Integer)source.getClientProperty("row");
Integer col = (Integer)source.getClientProperty("col");
if (row == null || col == null) {
System.err.println("!! Invalid cell");
return;
}
System.out.println("Clicked " + col + "x" + row);
getModel().expose(col, row);
}
};
int rowCount = model.getRows();
int colCount = model.getColumns();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
buttons = new JButton[rowCount * colCount];
for (int row = 0; row < rowCount; row++) {
for (int col = 0; col < colCount; col++) {
JButton btn = makeButton(col, row, model);
btn.addMouseListener(mouseListener);
gbc.gridx = col;
gbc.gridy = row;
add(btn, gbc);
buttons[row * rowCount + col] = btn;
}
}
}
public MineSweeperModel getModel() {
return model;
}
protected JButton makeButton(int col, int row, MineSweeperModel model) {
JButton btn = new JButton(Integer.toString(model.getValueAt(col, row))) {
#Override
public Dimension getPreferredSize() {
return new Dimension(35, 35);
}
};
btn.setFocusable(false);
btn.setFocusPainted(false);
btn.putClientProperty("row", row);
btn.putClientProperty("col", col);
return btn;
}
}
You will note two things.
I use get/setClientProperty to get and set the cell coordinates for the button within the model. This allows me to seed the int values without needing to format/parse them to/from a String, which is, frankly, messy
I also cheated and demonstrated the ability to pull the buttons grid coordinates directly from the GridBagLayout itself. I prefer to the first, but this is a nice side effect not many people know or make use of it.
When "clicked" (and you should be using an ActionListener, but you're apparently not meant to be using an ActionListener because you've not learnt about them ... which begs the question of, why are you using a JButton when ActionListener is the primary mechanism for monitoring for when it's triggered 🙄), the UI updates the model. If there are any changes to the model, the model's observer is notified, which then allows the UI to update its visual state.
I've not put any logic in to the model, apart from exposing the underlying value of the cell (difference between the visialMap and bombMap), so you'll need to do that
There are a number of ways to achieve this. You could simply include a line in your builder method that matches a button to a value from the g array and stores it in a hashmap or some other data structure like so mineHashMap.put(gridz[r][c], g[r][c]);, this way we can check the hashmap later in the mouse event method to find the correct value from the hashmap like so:
int value = mineHashMap.get(b);
b.setText(value+"");`
If starting from scratch, then a quick and easy/dirty solution would be to extend the JButton class to create a customJBotton which would store the integer value inside the class when you create the custom button, and you could contain other logic in it too. Then later when the button is clicked you can easily get the number in the mouse event like so b.setText(b.getMineValue()); or call a custom method you created in the custom button like so b.revealMine(); which would effectively do this.setText(mineValue);
There are many many other ways to do this, but the two options above would slot into your code quite easily. Custom painting on a JPanel rather than using buttons would also be a smart option but it does require more technical understanding and code.

Paint Method in an Applet (Sort Algorithms in Java)

I have two classes: One applet for the GUI and one class to sort numbers.
Sort Class:
public class Sortierung {
public int[] Zahlen = {5,2,3,1,4};
int z;
public static int zufallszahl (int z){
int dauer = ((int)(Math.random()*z))+1;
return dauer;
}
public void ArrayErstellen(int l){
int[] myIntArray = new int[l];
for(int f=0;f<myIntArray.length;f++){
myIntArray[f]=zufallszahl(10);
}
Zahlen=myIntArray;
}
public int[] BubbleSort() {
for(int p=0;p<Zahlen.length-1;p++){
for(int i=0;i<Zahlen.length-1;i++){
if(Zahlen[i]<Zahlen[i+1]){
continue; //beendet den derzeitigen Schleifenablauf
}
else{
z=Zahlen[i];
Zahlen[i]=Zahlen[i+1];
Zahlen[i+1]=z;
}
}
}
return Zahlen;
}
public int[] InsertionSort() {
int f = 0; //Variable 1
int j = 0; //Variable 2
for(int i = 1;i < Zahlen.length;i++){
j = i;
while((j>0)&&(Zahlen[j-1]>Zahlen[j])){
f = Zahlen[j-1];
Zahlen[j-1] = Zahlen[j];
Zahlen[j] = f;
j--;
}
}
return Zahlen;
}
public int[] SelectionSort(){
for (int i = 0; i < Zahlen.length - 1; i++){
int s = i; //Neue Variable für die Schleife
for (int j = i + 1; j < Zahlen.length; j++)
if (Zahlen[j] < Zahlen[s]){
s = j;
}
int smallerNumber = Zahlen[s];
Zahlen[s] =Zahlen[i];
Zahlen[i] = smallerNumber;
}
return Zahlen;
}
public void ArrayWiedergeben(int[] eimer){
for(int u=0;u<eimer.length;u++){
System.out.println(eimer[u]);
}
} }
Gui (Applet):
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Gui extends JApplet {
JTextField tf;
JButton b;
JButton k;
JLabel s;
JLabel u;
int anzahl;
int test = 0;
JPanel p = new JPanel();
JPanel h = new JPanel();
JPanel f = new JPanel();
Sortierung neu = new Sortierung();
Choice Sortierungsmethode = new Choice();
ActionListener startOhr = new ActionListener() {
public void actionPerformed(ActionEvent e) {
anzahl = Integer.parseInt(tf.getText());
if (anzahl > 100) {
tf.setText("Wert zu hoch.");
return;
}
neu.ArrayErstellen(anzahl);
tf.setText("Array[" + anzahl + "] erstellt.");
}
};
ActionListener sortOhr = new ActionListener() {
public void actionPerformed(ActionEvent e) {
switch (Sortierungsmethode.getSelectedIndex()) {
case 0:
int[] eimer = neu.BubbleSort();
neu.ArrayWiedergeben(eimer);
test = 1;
repaint();
break;
case 1:
int[] eimer2 = neu.InsertionSort();
neu.ArrayWiedergeben(eimer2);
break;
case 2:
int[] eimer3 = neu.SelectionSort();
neu.ArrayWiedergeben(eimer3);
break;
default:
break;
}
}
};
public void init() {
tf = new JTextField(8);
b = new JButton("Erstellen");
k = new JButton("Bestätigen");
s = new JLabel("Array Länge");
u = new JLabel("Sortmethode");
Sortierungsmethode.add("Bubblesort");
Sortierungsmethode.add("Insertionsort");
Sortierungsmethode.add("Selectionsort");
setLayout(new BorderLayout());
p.add(s);
p.add(tf);
p.add(b);
h.add(u);
h.add(Sortierungsmethode);
h.add(k);
this.add(p, BorderLayout.NORTH);
this.add(h, BorderLayout.CENTER);
this.add(f, BorderLayout.SOUTH);
b.addActionListener(startOhr);
k.addActionListener(sortOhr);
}
}
My intention is to draw the sorted array in a coordinate system with a paint
method. The problem is, that when I try to create a paint method, the whole screen is white and I cant see anything
You need to address several details:
You should create a class which overrides JPanel to do your custom drawing. You can create an instance of the class in your Gui class.
You should override paintComponet() rather than paint().
The first line in paintComponent(Graphics g) should be super.paintComponent(g) in order to ensure that the super class can paint itself.
You need to be careful that your sorting algorithm doesn't take over the main thread. This will cause your app to freeze and nothing will paint until the sorting has finished.
You need to create a Thread object and set it to call run method 30 times per second. In this method, call repaint() method of main JPanel.

How can i stop the program from skipping my check the second time around?

I am creating a program to take in sets of binary digits and convert them into hammingcodes (Effectively take in 8 digits, turn into 12, print out) but i am having trouble. Currently, i am using a JTextField for the user to enter their number, then they press a JButton to enter the data. I then do funky shit with that number to put it into a list and confirm that this is the last of the numbers they wish to enter. If they click a JButton called yes (New text in button, but same button) if goes on to do what i need. But if they click the other JButton called no, it goes back and repeats the same process. My problem is after clicking no once, the program stops allowing you to press no at the step to check if you want to add another list of numbers. IT appears to skip the check all together and assume they pressed yes as it does the rest of the working out thats done after all entry is finished.
My code is a tad messy due to messing with it for a few hours.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import javax.swing.*;
public class MainProgram extends JFrame
{
public MainProgram()
{
}
public static void main(String[] args)
{
MainProgram mp = new MainProgram();
mp.run();
}
private void run()
{
java.util.List<Integer> streamSplit = new ArrayList<>();
java.util.List<Integer> tempEight = new ArrayList<>();
java.util.List<Integer> finalStream = new ArrayList<>();
yes.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
checkYes = true;
}
});
no.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
checkNo = true;
}
});
init();
yesChange("Enter");
boolean confirm = false;
int aCheck = 0;
while (aCheck == 0)
{
confirm = false;
while (!confirm)
{
setTopText("<html>Please enter your next 8 bits. Do not enter more than 8 bits.<br> Press Enter when done</html>");
yesChange("Enter");
confirm = checkYes();
}
confirm = false;
setTopText("Digits Successfully added.");
int stream = checkInput();
do
{
streamSplit.add(stream % 10);
stream /= 10;
} while (stream != 0);
setYesNo();
setTopText("<html>Are you finished entering streams?</html>");
yesChange("YES");
noChange("NO");
aCheck = 2;
checkYes();
checkNo();
while (aCheck == 2)
{
if ( checkNo())
{
aCheck = 0;
System.out.println("CrapNo");
}
else if (checkYes())
{
aCheck = 1;
System.out.println("CrapYes");
}
}
}
int arrayLength = streamSplit.size();
int bufferLength = 8 - arrayLength % 8;
int numberOfStreams = 0;
if (bufferLength != 8)
{
numberOfStreams = arrayLength / 8 + 1;
} else
{
numberOfStreams = arrayLength / 8;
}
int tempStreams = numberOfStreams;
System.out.println(numberOfStreams + "<Streams Buffer>" + bufferLength);
while (bufferLength > 0 && bufferLength != 8)
{
streamSplit.add(0);
bufferLength--;
}
while (tempStreams > 0)
{
for (int i = 0; i < 8; i++)
{
tempEight.add(streamSplit.get(i));
}
if ((tempEight.get(0) + tempEight.get(1) + tempEight.get(3) + tempEight.get(4) + tempEight.get(6)) % 2 == 0)
{
tempEight.add(0, 0);
} else
{
tempEight.add(0, 1);
}
if ((tempEight.get(1) + tempEight.get(3) + tempEight.get(5) + tempEight.get(6) + tempEight.get(7)) % 2 == 0)
{
tempEight.add(1, 0);
} else
{
tempEight.add(1, 1);
}
if ((tempEight.get(3) + tempEight.get(4) + tempEight.get(5) + tempEight.get(8) + tempEight.get(9)) % 2 == 0)
{
tempEight.add(3, 0);
} else
{
tempEight.add(3, 1);
}
if ((tempEight.get(7) + tempEight.get(8) + tempEight.get(9) + tempEight.get(10)) % 2 == 0)
{
tempEight.add(7, 0);
} else
{
tempEight.add(7, 1);
}
tempStreams--;
for (int i = 0; i < 12; i++)
{
finalStream.add(tempEight.get(0));
tempEight.remove(0);
}
}
Collections.reverse(streamSplit);
System.out.print("Your original bit-stream was: ");
for (int i = 0; i < numberOfStreams * 2; i++)
{
for (int j = 0; j < 4; j++)
{
System.out.print(streamSplit.get(j + (i * 4)));
}
System.out.print(" ");
}
System.out.println();
System.out.print("Your new HammingCode bit-stream is: ");
for (int i = 0; i < numberOfStreams * 3; i++)
{
for (int j = 0; j < 4; j++)
{
System.out.print(finalStream.get(j + (i * 4)));
}
System.out.print(" ");
}
System.out.println();
}
public Boolean checkYes = false;
public Boolean checkNo = false;
private JFrame frame = new JFrame("Absolute Layout Example");
private JPanel contentPane = new JPanel();
private JLabel topText = new JLabel("Welcome to my Hamming Code Generator", JLabel.CENTER);
private JTextField inputText = new JTextField();
private JButton yes = new JButton("YES");
private JButton no = new JButton("NO");
public void init()
{
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane.setOpaque(true);
contentPane.setBackground(Color.WHITE);
contentPane.setLayout(null);
topText.setLocation(0, 0);
topText.setSize(400, 50);
topText.setBorder(BorderFactory.createLineBorder(Color.black));
inputText.setLocation(0,50);
inputText.setSize(400,75);
inputText.setBorder(BorderFactory.createLineBorder(Color.black));
yes.setSize(80, 40);
yes.setLocation(60, 135);
no.setSize(80, 40);
no.setLocation(260, 135);
contentPane.add(topText);
contentPane.add(inputText);
contentPane.add(yes);
contentPane.add(no);
frame.setContentPane(contentPane);
frame.setSize(400, 225);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public void setTopText(String s)
{
topText.setText(s);
}
public void setYesNo()
{
checkYes = false;
checkNo = false;
}
public Boolean checkYes() {return checkYes;}
public Boolean checkNo() {return checkNo;}
public int checkInput()
{
String temp1 = inputText.getText();
int temp = Integer.parseInt(temp1);
return temp;
}
public void yesChange(String s)
{
yes.setText(s);
}
public void noChange(String s)
{
no.setText(s);
}
}
I find it tough to answer this question not fully knowing what your code is doing, especially the part where you "... do funky #### with that number..."
But I do know that you have significant issues with your program structure, especially within your lengthy run() method where you have numerous nested while (...) loops and do-while loops, code constructs that might seem at home within a linear processing console program but which seems out of place within an event-driven Swing GUI.
What I suggest that you do is try to use some state-dependent coding. For instance, you could give your class the boolean variables, enteringData and dataValidYet, to represent two key states: whether the user is now entering data into the JTextField, and whether that data has yet been validated yet. And then within your JButton ActionListeners, use if and if/else blocks to decide what to do on button push depending on the state of these boolean fields, and likely other key fields of the class.
For a code "skeleton" example, one that doesn't yet do anything, but hopefully will show you the structure I'm talking about:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
#SuppressWarnings("serial")
public class StateMachine extends JPanel {
private static final String INITIAL_TITLE = "Please enter your next 8 bits. "
+ "Do not enter more than 8 bits.\n"
+ "Press Enter when done";
private static final String ARE_YOU_FINISHED = "Are you finished entering streams?";
private static final String YES = "Yes";
private static final String ENTER = "Enter";
private static final String NO = "No";
private static int GAP = 8;
private static final int COLUMNS = 30;
// this is a JTextArea built to look like a JLabel
private JTextArea topTextArea = new JTextArea(2, COLUMNS);
private JTextField dataEntryField = new JTextField(COLUMNS);
private JButton yesEnterButton = new JButton(ENTER);
private JButton noButton = new JButton(NO);
private boolean enteringData = true;
private boolean dataValidYet = false;
public StateMachine() {
yesEnterButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
yesEnterButtonActionPerfromed(e);
}
});
noButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
noButtonActionPerfromed(e);
}
});
topTextArea.setWrapStyleWord(true);
topTextArea.setLineWrap(true);
topTextArea.setFocusable(false);
topTextArea.setEditable(false);
topTextArea.setOpaque(false);
topTextArea.setText(INITIAL_TITLE);
JPanel innerButtonPanel = new JPanel(new GridLayout(1, 0, GAP, 0));
innerButtonPanel.add(yesEnterButton);
innerButtonPanel.add(noButton);
JPanel outerButtonPanel = new JPanel();
outerButtonPanel.add(innerButtonPanel);
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new BorderLayout(GAP, GAP));
add(topTextArea, BorderLayout.PAGE_START);
add(dataEntryField, BorderLayout.CENTER);
add(outerButtonPanel, BorderLayout.PAGE_END);
}
protected void noButtonActionPerfromed(ActionEvent e) {
// TODO depending on state of enteringData and dataValidYet booleans
// change text in buttons, do things with JTextField data
// set state of enteringData and dataValidYet booleans
if (enteringData) {
// a no press is meaningless if entering data
return;
}
// .... more
}
private void yesEnterButtonActionPerfromed(ActionEvent e) {
// TODO depending on state of enteringData and dataValidYet booleans
// change text in buttons, do things with JTextField data
// set state of enteringData and dataValidYet booleans
if (enteringData) {
topTextArea.setText(ARE_YOU_FINISHED);
yesEnterButton.setText(YES);
yesEnterButton.setActionCommand(YES);
enteringData = false;
return;
}
// .... more
}
private static void createAndShowGui() {
StateMachine mainPanel = new StateMachine();
JFrame frame = new JFrame("State Machine");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Also, as a "side" recommendation, one unrelated to your main problem, understand that null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
Note that if this were my program, I would use more indirection including creating separate classes to separate out the GUI portion of the program from the logic portion.

Method not running when initiated in another class

so I have a few classes but the two in question are my Character class and Gui class
In my Character class I have (essentially)
public class Character implements Serializable
{
Gui gui = new Gui();
public Character(String name,int row,int col,int bounds){
this.name = name;
this.row = row;
this.col = col;
this.bounds = bounds;
}
public String toString()
{
gui.labels(row, col);
return (name + " at (" + row + "," + col + ")\t");
}
}
And then in my Gui class I have this
public void labels(int x, int y)
{
label[0][0] = label00;
label[0][1] = label01;
label[0][2] = label02;
label[0][3] = label03;
label[1][0] = label10;
label[1][1] = label11;
label[1][2] = label12;
label[1][3] = label13;
label[2][0] = label20;
label[2][1] = label21;
label[2][2] = label22;
label[2][3] = label23;
label[3][0] = label30;
label[3][1] = label31;
label[3][2] = label32;
label[3][3] = label33;
JLabel jLabel = label[x][y];
jLabel.setText("0");
jLabel.setText("Test");
}
And what is meant to happen is the toString function is meant to send the Col and Row values to the labels function in the Gui and then the Gui sets the label accordingly
However it just doesn't do anything and I don't know why, but if I make a test button on the Gui and then make it call the function labels like this for example
JButton settingsButton = new JButton("Settings");
settingsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
labels(3, 1);
}
});
It works perfectly fine, am I missing something here? I can't quite understand why this isn't working

How can I make my java program not create multiple instances when calling the constructor with parameters?

I have a homework assignment that provides a GUI interface and displays ten teams, each represented by a button. Each button has a radio button to the left of it that allows the user to select the radio and then click another teams button to move the selected team to that position. The selected team will move and the other teams will shift either up or down.
This is not the issue. The code is complete but, I have a problem. Currently it works but after each click of a button the program makes a new call to the constructor which then opens another instance of the program, but the data shifts correctly.
I'm looking for a suggestion on how to make this work. I tried to make it call the method that creates the GUI but it doesn't work properly and throws a nasty exception.
My code is below and the area of concern is line 99 and 100. Line 99 is commented out. It is what I tried instead of the new constructor call on line 100.
I hope this makes sense and thanks in advance for any suggestions.
Note: (I'm not looking for someone to complete my homework for me. I have completed this code from scratch and I have exhausted myself trying to figure this thing out. Thanks!)
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class P03TopTenTeams extends JFrame {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
String[] teams = {"Texas", "Vanderbilt", "Florida", "Missouri","Arkansas", "Kentucky", "Alabama", "Tennessee", "Georgia","Louisiana"};
new P03TopTenTeams(teams);
}
private JPanel panel1;
private JPanel panel2;
private JButton[] btn = new JButton[10];
private JRadioButton[] rbtn = new JRadioButton[10];
private ButtonGroup bg1 = new ButtonGroup();
private ButtonGroup bg2 = new ButtonGroup();
public P03TopTenTeams(String[] teams) {
buildWindow(teams);
}
private void buildWindow(String[] teams) {
int index;
this.setSize(300, 500);
this.setLocationRelativeTo(null);
this.setTitle("Top Ten Teams");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
panel1 = new JPanel();
panel1.setLayout(new GridLayout(10, 1));
for (index = 0; index < 10; index++) {
rbtn[index] = new javax.swing.JRadioButton(
Integer.toString(index + 1));
bg1.add(rbtn[index]);
panel1.add(rbtn[index]);
}
panel2 = new JPanel();
panel2.setLayout(new GridLayout(10, 1));
BtnHdlr btnhdlr = new BtnHdlr();
for (index = 0; index < 10; index++) {
btn[index] = new javax.swing.JButton(teams[index]);
bg2.add(btn[index]);
panel2.add(btn[index]);
btn[index].addActionListener(btnhdlr);
}
this.add(panel1, BorderLayout.WEST);
this.add(panel2, BorderLayout.CENTER);
this.setVisible(true);
}
private class BtnHdlr implements ActionListener {
public void actionPerformed(ActionEvent event) {
int from = 0;
int to = 0;
String[] teams = new String[10];
int index;
for (index = 0; index < bg1.getButtonCount(); index++) {
teams[index] = btn[index].getText();
if (rbtn[index].isSelected() == true) {
from = index;
}
if (btn[index].getText().equals(event.getActionCommand())) {
to = index;
}
}
updateTeamsArray(teams, from, to);
}
}
private void updateTeamsArray(String[] teams, int from, int to) {
int index;
String valueFrom = teams[from];
if (from < to) {
for (index = from; index < to; index++) {
teams[index] = teams[index + 1];
}
teams[to] = valueFrom;
} else {
for (index = from; index > to; index--) {
teams[index] = teams[index - 1];
}
teams[to] = valueFrom;
}
//buildWindow(teams);
new P03TopTenTeams(teams);
}
}
The solution seems insanely obvious: if you don't want the constructor called, don't call it! Simply get the constructor call out of your updateTeamsArray method.
More specifically:
Remove all buttons from the container that holds them
Re-add the buttons to that container in the new order
Call revalidate() and repaint() on the container.
Or more simply, you can simply rename your JButtons with the array names in the new order.
For example:
private void updateTeamsArray(String[] teams, int from, int to) {
int index;
String valueFrom = teams[from];
if (from < to) {
for (index = from; index < to; index++) {
teams[index] = teams[index + 1];
}
teams[to] = valueFrom;
} else {
for (index = from; index > to; index--) {
teams[index] = teams[index - 1];
}
teams[to] = valueFrom;
}
// buildWindow(teams);
// new P03TopTenTeams(teams); // delete this!
// ***** add this *****
for (int i = 0; i < teams.length; i++) {
btn[i].setText(teams[i]);
}
}

Categories