I'm writing a program in Java that is supposed to function as a truth table generator for a boolean expression. However, I'm having a lot of trouble with the brackets. The errors start when a pair of brackets enclose the entire expression (produces a runtime error), or if there aren't enough brackets in the expression (producing the wrong result).
Here's all my code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.lang.Math;
public class BooleanAlgebra
{
public static void main(String[] args)
{
new BooleanAlgebra();
}
private JFrame frame;
private JPanel panel;
private JTextField textField;
private JButton and;
private JButton or;
private JButton not;
private JButton nor;
private JButton nand;
private JButton xor;
private JButton xnor;
private JPanel panel2;
private JButton generate;
private JButton close;
private ArrayList<Character> variables;
private char[] chars;
public BooleanAlgebra()
{
frame = new JFrame("Boolean Algebra");
frame.setSize(new Dimension(800, 800));
textField = new JTextField("(x+y)");
and = new JButton("AND [ x & y ]");
or = new JButton("OR [ x + y ]");
not = new JButton("NOT [ ! x ]");
nor = new JButton("NOR [ ! ( x + y ) ]");
nand = new JButton("NAND [ ! ( x & y ) ]");
xor = new JButton("XOR [ ( x & ! y ) + ( ! x & y ) ]");
xnor = new JButton("XNOR [ ( x & y ) + ( ! x & ! y ) ]");
generate = new JButton("Generate Table");
close = new JButton("Exit");
ButtonHandler buttons = new ButtonHandler();
and.addActionListener(buttons);
or.addActionListener(buttons);
not.addActionListener(buttons);
nor.addActionListener(buttons);
nand.addActionListener(buttons);
xor.addActionListener(buttons);
xnor.addActionListener(buttons);
generate.addActionListener(buttons);
close.addActionListener(buttons);
panel2 = new JPanel();
panel2.setLayout(new GridLayout(1, 2));
panel2.add(generate);
panel2.add(close);
panel = new JPanel();
panel.setLayout(new GridLayout(9, 1));
panel.add(textField);
panel.add(and);
panel.add(or);
panel.add(not);
panel.add(nor);
panel.add(nand);
panel.add(xor);
panel.add(xnor);
panel.add(panel2);
frame.add(panel);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private boolean isLetter(char a)
{
if((a > 64 && a < 91) || (a > 96 && a < 123))
{
return true;
}
return false;
}
private void generate()
{
chars = ("(" + textField.getText() + ")").toCharArray();
variables = new ArrayList<Character>();
for(int i = 0; i < chars.length; i++)
{
if(isLetter(chars[i]))
{
if(!variables.contains(chars[i]))
{
variables.add(chars[i]);
}
}
}
Collections.sort(variables);
String[] heads = new String[variables.size() + 1];
for(int i = 0; i < heads.length - 1; i++)
{
heads[i] = variables.get(i).toString();
}
heads[heads.length - 1] = textField.getText();
int row = (int)Math.pow(2, variables.size());
int column = variables.size() + 1;
int count = 0;
int max = 1;
Integer[][] array = new Integer[row][column];
for(int a = column - 2; a >= 0; a--)
{
for(int b = 0; b < row; b++)
{
if(count < max)
{
array[b][a] = 0;
count++;
}
else if(count >= max)
{
array[b][a] = 1;
count++;
if(count == max * 2)
{
count = 0;
}
}
}
max = max * 2;
}
for(int i = 0; i < row; i++)
{
array[i][column - 1] = 0;
}
int[][] arrayCopy = new int[row][column];
for(int i = 0; i < row; i++)
{
for(int j = 0; j < column; j++)
{
arrayCopy[i][j] = array[i][j];
}
}
for(int i = 0; i < row; i++)
{
array[i][column - 1] = calculate(arrayCopy[i]);
}
JTable table = new JTable(array, heads);
JFrame frame2 = new JFrame(textField.getText());
frame2.add(new JScrollPane(table));
frame2.pack();
frame2.setVisible(true);
table.setEnabled(false);
}
private int calculate(int[] array)
{
Stack<Character> ops = new Stack<Character>();
Stack<Integer> values = new Stack<Integer>();
for(int i = 0; i < chars.length; i++)
{
char s = chars[i];
if (s == '(') ;
else if (s == '+') ops.push(s);
else if (s == '&') ops.push(s);
else if (s == '!') ops.push(s);
else if (s == ')')
{
char operation = ops.pop();
int v = values.pop();
if (operation == '+') v = or(values.pop(), v);
else if (operation == '&') v = and(values.pop(), v);
else if (operation == '!') v = not(v);
values.push(v);
}
else if(isLetter(s))
{
values.push(array[variables.indexOf(s)]);
}
}
return values.pop();
}
private int and(int a, int b)
{
if(a == 1 && b == 1)
{
return 1;
}
return 0;
}
private int or(int a, int b)
{
if(a == 0 && b == 0)
{
return 0;
}
return 1;
}
private int not(int a)
{
if(a == 1)
{
return 0;
}
return 1;
}
public class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == and)
{
textField.setText(textField.getText() + "(x&y)");
textField.requestFocus(true);
}
if(event.getSource() == or)
{
textField.setText(textField.getText() + "(x+y)");
textField.requestFocus(true);
}
if(event.getSource() == not)
{
textField.setText(textField.getText() + "(!x)");
textField.requestFocus(true);
}
if(event.getSource() == nor)
{
textField.setText(textField.getText() + "!(x+y)");
textField.requestFocus(true);
}
if(event.getSource() == nand)
{
textField.setText(textField.getText() + "!(x&y)");
textField.requestFocus(true);
}
if(event.getSource() == xor)
{
textField.setText(textField.getText() + "(x&(!y))+(((!x)&y))");
textField.requestFocus(true);
}
if(event.getSource() == xnor)
{
textField.setText(textField.getText() + "(x&y)+(((!x)&(!y)))");
textField.requestFocus(true);
}
if(event.getSource() == generate)
{
generate();
}
if(event.getSource() == close)
{
System.exit(0);
}
}
}
}
I need help making this work without the user having to input the brackets correctly themselves (I want the program to fix up the expression, or somehow evaluate it without waiting for a close bracket like I did here).
To test the code and see the errors, input the following when running it:
(x+y) --> runtime error because brackets surround the whole expression
x+y+z --> incorrect output table
x+y --> works
x&y --> works
!!x --> incorrect output table
Please explain this to me. Thanks!