I'm stacked!! I am relatively new to java and I have been days searching the web to solve my problem without success, its now time to ask for your help.
I cannot...(actually do not know) how to change the actionlistener (actionPerformed) after the second click in an array of JButtons. Please find the code below so that you can guide me.
This is how the program performs right now.
On the 1st click on the grid, the border of the button clicked will change to 'blue' and another button will change its boarder to 'red'. on the next click the same action is performed.
What I need is to change action when the 'red' bordered button is clicked, lets say change the color of the buttons from the 'red' to the 'blue' buttons.(x 3 buttons).
The logic about how to perform the final result I think I can do on my own but my problem is how to change the action when the red bordered button is clicked.
Your help is much appreciated!
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class ChangeGrid
{
private JButton[][] bu1 = new JButton[10][10];
public ChangeGrid(JFrame frame)
{
super();
JPanel pCenter = new JPanel();
JPanel pTop = new JPanel();
frame.add(pCenter, BorderLayout.CENTER);
frame.add(pTop, BorderLayout.NORTH);
JPanel Grid10x10 = new JPanel(new GridLayout(10,10));
pCenter.add(Grid10x10);
for(int c = 0; c< 10; c++)
{
for (int r = 0; r< 10; r++)
{
bu1[c][r] = new JButton("X");
Grid10x10.add(bu1[c][r]);
final int i = c;
final int j = r;
bu1[i][j].addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
int f = (3-1);
bu1[i][j].setBorder(BorderFactory.createLineBorder(Color.BLUE, 2));
if ((j+f)<=9)
{
bu1[i][j+f].setBorder(BorderFactory.createLineBorder(Color.RED, 2));
}
else
{
JOptionPane.showMessageDialog(null,"move your 1st click more to the center");
}
}
});
}
}
}
}
import javax.swing.JFrame;
public class GUIFrame extends JFrame
{
public GUIFrame()
{
super("Grid 10 x 10");
this.setSize(1350, 700);
this.setVisible(true);
this.setResizable(true);
this.setDefaultCloseOperation(GUIFrame.EXIT_ON_CLOSE);
}
}
import javax.swing.JFrame;
public class Main
{
public static void main(String args[])
{
JFrame frame = new GUIFrame();
ChangeGrid pC = new ChangeGrid(frame);
frame.pack();
}
}
You can change your ActionListener like next:
bu1[i][j].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int f = (3 - 1);
Border border = bu1[i][j].getBorder();
if(border instanceof LineBorder){
LineBorder lBorder = (LineBorder) border;
if(lBorder.getLineColor().equals(Color.RED)){
//red border clicked
redBorderAction(bu1[i][j]);
return;
}
}
defaultAction(i,j,f);
}
});
And other methods:
private void defaultAction(int i, int j, int f) {
bu1[i][j].setBorder(BorderFactory.createLineBorder(Color.BLUE, 2));
if ((j + f) <= 9) {
bu1[i][j + f].setBorder(BorderFactory.createLineBorder(Color.RED, 2));
} else {
JOptionPane.showMessageDialog(null,"move your 1st click more to the center");
}
}
private void redBorderAction(JButton btn) {
btn.setBorder(BorderFactory.createLineBorder(Color.BLUE, 2));
}
Related
I'm trying to make a grid of 20px x 20px buttons that I define as "cells", blank by default, no special decorations such as shading, and change color when clicked. (They are meant to show "1" just for testing purposes). I make a Cell class to define these buttons, give each an ActionListener.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Cell implements ActionListener
{
private JButton button;
private EditorPanel editorPanel;
public Cell(EditorPanel editorPanel){
button = new JButton("1'");
button.addActionListener(listener -> colorCell());
button.setPreferredSize(new Dimension(20,20));
button.setMargin(new Insets(0,0,0,0));
button.setOpaque(true);
button.setContentAreaFilled(false);
this.editorPanel = editorPanel;
}
public JButton getButton() {
return button;
}
public void colorCell()
{
button.setBackground(Color.BLACK);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
and then use an array of Cell objects (cells) in my EditorPanel class to create a grid of these buttons with dimensions defined by "col" and "row".
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class EditorPanel{
public JFrame jframe;
public JPanel jpanel;
public static EditorPanel editorPanel;
public Render render;
public static final int col = 45, row = 45, tile_size=20;
public static final int panelWidth=900, panelHeight=900;
public Dimension dim;
public int coloredPixels;
public Cell[][] cells;
public void getFrame() {
editorPanel = new EditorPanel();
dim = Toolkit.getDefaultToolkit().getScreenSize();
jframe = new JFrame("Pixel Art Creator");
jframe.setVisible(true);
jframe.setSize(panelWidth+17, panelHeight+40);
jframe.setLocation(dim.width/2 - jframe.getWidth()/2, dim.height/2 - jframe.getHeight()/2);
jframe.add(render = new Render());
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private JPanel addCells()
{
cells=new Cell[row][col];
JPanel panel = new JPanel(new GridLayout(row, col));
for(int i = 0; i< row; i++){
for(int j = 0; j<col; j++){
cells[i][j] = new Cell(this);
panel.add(cells[i][j].getButton());
}
}
return panel;
}
public static void main (String[] args)
{
editorPanel = new EditorPanel();
editorPanel.getFrame();
editorPanel.addCells();
}
}
I then try to add each created Cell object that I attempted to put into the cells array in the addCells() method and add it to my JPanel. When I run this code I don't get any buttons, meaning that these buttons aren't being added to JPanel. How should I go about this?
So, two "significant" issues:
editorPanel.addCells(); never adds the JPanel that it creates to anything, so it will never be displayed
Calling JFrame#setVisible BEFORE you've finished establishing the UI can cause the UI elements not to show up on the UI. You can fix this by calling revalidate and repaint on the container which is changed, but if possible, simply get the UI established first, then make it visible
I would, however, suggest a slight change in approach. Rather then making Cell a class which contains a JButton, and then exposing that button to other aspects of your UI, I would make Cell a component and simply add it to the what ever container you want, for example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Test");
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
for (int y = 0; y < 20; y++) {
gbc.gridy = y;
for (int x = 0; x < 20; x++) {
gbc.gridx = x;
add(new Cell(), gbc);
}
}
}
}
public class Cell extends JPanel {
public Cell() {
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
colorCell();
}
});
setBorder(new LineBorder(Color.GRAY));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(20, 20);
}
protected void colorCell() {
if (getBackground() != Color.DARK_GRAY) {
setBackground(Color.DARK_GRAY);
} else {
setBackground(null);
}
}
}
}
Now, I've just used a plain old JPanel in the this case, but you could just as easily extend from a JButton or JToggledButton ... but I might be tempted to use a factory pattern instead, but that's me.
The purpose of using a GridBagLayout is to allow the frame and outer containers to be resized without changing the size of the Cells themselves, unlike GridLayout, which will try and make the cells fill the available space
I am trying to make a multiplication table made of buttons with the math fact on them that changes to the product when pressed, then returned to the fact when pressed again. Got the first part but can't figure out how to get it to return to the original button setting. I have my program constructed in 2 classes. First makes the buttons and populates them with original facts. Used nested loop to write the text (math facts) on the buttons.
import java.awt.ComponentOrientation;
import java.awt.GridLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
public class Grid {
public static void main(String args[]){
JFrame frame = new JFrame("Grid Layout");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setResizable(false);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout (9, 9, 5, 5));
panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
int i, j;
for (i = 1; i<=9; i++){
for (j = 1; j <= 9; j++){
FactButton button =new FactButton();
button.setText(i + " x " + j);
panel.add(button);
}
}
frame.add(panel);
}
}
Second class defines what buttons do when pressed. I made two cases. The first is the default, second changes the button to present product. This works fine when pressed the first time. When button is pressed a second time I get error messages and nothing changes. Can I change my first case to integers based on
the button's location on the panel (column, row)? How do I do this? Other suggestions?
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.Color;
import java.awt.event.ActionEvent;
public class FactButton extends JButton implements ActionListener{
private static final long serialVersionUID = 1L;
public FactButton() {
this.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
String prob = this.getText();
String left = prob.substring(0, prob.indexOf(" "));
String right = prob.substring(prob.indexOf(" ")+3, prob.length() );
int i = Integer.parseInt(left);
int j = Integer.parseInt(right);
int v=0;
v++;
v%=2;
switch(v){
case 0:
this.setText(null);
break;
case 1:
this.setText(i*j+"");
this.setBackground(Color.WHITE);
this.setContentAreaFilled(false);
this.setOpaque(true);
break;
}
}
}
It switches to the product on first press. Breaks on second. Thought it would go back to a blank button. How can I get it to show the original math fact?
Keep the numbers inside FactButton as members. Then you can use them whenever you want. In the current situation you are parsing numbers from the button text. But after first click text of the button is changing. So you are losing the numbers which set during instantiation.
Change your FactButton with this:
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.Color;
import java.awt.event.ActionEvent;
public class FactButton extends JButton implements ActionListener {
private final static int PRODUCT_STATE = 0;
private final static int FACT_STATE = 1;
private int buttonState = FACT_STATE;
private int firstNumber;
private int secondNumber;
public FactButton(int firstNumber, int secondNumber) {
this.firstNumber = firstNumber;
this.secondNumber = secondNumber;
this.setText(firstNumber + " x " + secondNumber);
this.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
switch (buttonState) {
case PRODUCT_STATE:
this.setText(firstNumber + " x " + secondNumber);
this.setBackground(null);
this.setContentAreaFilled(true);
buttonState = FACT_STATE;
break;
case FACT_STATE:
this.setText(firstNumber * secondNumber + "");
this.setBackground(Color.WHITE);
this.setContentAreaFilled(false);
this.setOpaque(true);
buttonState = PRODUCT_STATE;
break;
}
}
}
And do not set button's text after instantiation. Do it like this:
FactButton button =new FactButton(i, j);
//not needed
//button.setText(i + " x " + j);
panel.add(button);
Answer is here :)
First of all, your thing with the switch is very messy, so i corrected it using regex: it checks if the text is only a number or something else, so if its on the form "64" or "8 x 8" by example
In your case, i won't be using column and row. Imagine you suddenly added a row or something... You should use HashMap, by setting the default value of every button in it, like this:
Grid.java :
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.GridLayout;
import java.util.HashMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Grid {
static HashMap<JButton, String> map = new HashMap<JButton, String>();
public static void main(String args[]){
JFrame frame = new JFrame("Grid Layout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 800);
frame.setResizable(false);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout (9, 9, 5, 5));
panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
int i, j;
for (i = 1; i<=9; i++){
for (j = 1; j <= 9; j++){
FactButton button =new FactButton();
String txt = i + " x " + j;
button.setText(txt);
map.put(button, txt);
panel.add(button);
}
}
frame.add(panel);
frame.setVisible(true);
}
public static String getOriginalFromButton(JButton button){
return map.get(button);
}
}
FactButton.java:
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.Color;
import java.awt.event.ActionEvent;
public class FactButton extends JButton implements ActionListener{
private static final long serialVersionUID = 1L;
public FactButton() {
this.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
String prob = this.getText();
int i = 0,j = 0;
if(!prob.matches("-?\\d+")){//it was on the "x*y" form
String left = prob.substring(0, prob.indexOf(" "));
String right = prob.substring(prob.indexOf(" ")+3, prob.length());
i = Integer.parseInt(left);
j = Integer.parseInt(right);
this.setText(i*j+"");
this.setBackground(Color.WHITE);
this.setContentAreaFilled(false);
this.setOpaque(true);
} else {//so it was on the form of a number
this.setText(Grid.getOriginalFromButton(this));
//any other changes like color
}
}
}
Hope it helped :)
I think the error message is occuring because of this line;
String right = prob.substring(prob.indexOf(" ")+3, prob.length() );
If the result is shown, let's say it's 42, prob.indexOf(" ") returns -1, therefore it's equivalent to prob.substring(2, 2); Since 42 is only 2 characters long, you can't reach it's 2nd index, which would be the 3rd letter. Also, I don't think that
int v=0;
v++;
v%=2;
is doing much. v always be 1
The simplest solution to your problem would be to just parse the original text to the FactButton constructor. You might also want to use a JToggleButton instead of a JButton to let it show it's state.
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.JFrame;
public class Grid {
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Grid Layout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setResizable(false);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(9, 9, 5, 5));
int i, j;
for (i = 1; i <= 9; i++) {
for (j = 1; j <= 9; j++) {
FactButton button = new FactButton(i + " x " + j);
panel.add(button);
}
}
frame.add(panel);
frame.setVisible(true);
}
});
}
}
class FactButton extends JToggleButton {
private static final long serialVersionUID = 1L;
String orgText;
public FactButton(String orgText) {
this.orgText = orgText;
setText(orgText);
addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent evt) {
if (evt.getStateChange() == ItemEvent.SELECTED) {
String prob = getText();
String left = prob.substring(0, prob.indexOf(" "));
String right = prob.substring(prob.indexOf(" ") + 3, prob.length());
int i = Integer.parseInt(left);
int j = Integer.parseInt(right);
setText(i * j + "");
} else if (evt.getStateChange() == ItemEvent.DESELECTED) {
setText(orgText);
}
}
});
}
}
There is the code of my simple Program.
There are four textFields.
when cursor is on first textField JOptionPane is Created and when I press ok
cursor moves to next field and OptionPane is created again
and so on
when cursor is on fourth field and I click OK on OptionPane,cursor moves to fifth field "f".
when cursor is in field,I print the possition of the field in array: System.out.println("first or Second or Third or Fourth")
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Hello extends JFrame implements ActionListener, FocusListener {
public JTextField[] fields = new JTextField[4];
public JPanel panel = new JPanel();
public JTextField f = new JTextField(12);
public static void main(String[] args) {
new Hello();
}
public Hello() {
for (int i = 0; i < 4; i++) {
fields[i] = new JTextField(12);
fields[i].addFocusListener(this);
panel.add(fields[i]);
}
add(panel);
add(f);
setTitle("Hello World");
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(920, 420);
setLocation(100, 100);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent ae) {
}
#Override
public void focusGained(FocusEvent fe) {
if (fe.getSource() == fields[0]) {
JOptionPane.showMessageDialog(null, "HELLO");
fields[1].requestFocus();
System.out.println("FIRST");
} else if (fe.getSource() == fields[1]) {
JOptionPane.showMessageDialog(null, "HELLO");
fields[2].requestFocus();
System.out.println("SECOND");
} else if (fe.getSource() == fields[2]) {
JOptionPane.showMessageDialog(null, "HELLO");
fields[3].requestFocus();
System.out.println("THIRD");
} else if (fe.getSource() == fields[3]) {
JOptionPane.showMessageDialog(null, "HELLO");
f.requestFocus();
System.out.println("FOURTH")
}
}
#Override
public void focusLost(FocusEvent fe) {
}
}
When there is no OptionPane,the cursor moves forward from first field to the fourth and prints:
FIRST
SECOND
THIRD
FOURTH
but when there is JOptionPane
the output is :
FIRST
SECOND
FIRST
SECOND
THIRD
SECOND
THIRD
FOURTH
THIRD
FOURTH
FOURTH
One can see that after second field it comes back to first,
after third field it comes back to second,instead of to go to fourth
after fourth field it comes back to third.
I want to know why? and how can I fix this
The problem is that every time you click OK on the JOptionPane, the focus is returned to the last JTextField active before the JOptionPane was shown, so a new requestFocus event is added to the event queue for that control. Actually after the first time you click OK while executing your code, several dialogs are fire, you just don't see it because you show the same text (HELLO) every time. I have changed your code to make it work. Hope it helps!
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class testOptionPane extends JFrame implements ActionListener, FocusListener {
public ArrayList<JTextField> fields = new ArrayList<>();
public JPanel panel = new JPanel();
public JTextField f = new JTextField(12);
private int currentField = 0;
private boolean focusReturned = false;
public static void main(String[] args) {
new testOptionPane();
}
public testOptionPane() {
for (int i = 0; i < 4; i++) {
JTextField tf = new JTextField(12);
fields.add(tf);
tf.addFocusListener(this);
panel.add(tf);
}
add(panel);
fields.add(f);
add(f);
setTitle("Hello World");
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(920, 420);
setLocation(100, 100);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent ae) {
}
#Override
public void focusGained(FocusEvent fe) {
if (fe.getSource() == fields.get(currentField)) {
if (!focusReturned) {
JOptionPane.showMessageDialog(this, "focus on field " + String.valueOf(currentField));
System.out.println(currentField);
focusReturned = true;
} else {
currentField++;
focusReturned = false;
if (currentField < fields.size()) {
fields.get(currentField).requestFocus();
}
}
}
}
#Override
public void focusLost(FocusEvent fe) {
}
}
When my jTextArea is in focus it allows text highlighting, but it doesn't show the text selection when it loses focus. Is it possible to continue displaying the text highlighting even if the user moves focus to another component on the related jFrame?
One simple workaround for caret selection is a simple subclassing of DefaultCaret:
textArea.setCaret(new DefaultCaret() {
#Override
public void setSelectionVisible(boolean visible) {
super.setSelectionVisible(true);
}
});
but doesn't show selection on text when looses focus.
there are three ways:
use JTextPane, see Oracle tutorial
easiest in the case that we talking about selection as painting artefact from Mouse Event see my question How to override DefaultCaret#setBlinkRate(), great knowledge and answer by #camickr
or programatically override Highlighter
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
public class MultiHighlight implements ActionListener {
private JTextComponent comp;
private String charsToHighlight;
public MultiHighlight(JTextComponent c, String chars) {
comp = c;
charsToHighlight = chars;
}
#Override
public void actionPerformed(ActionEvent e) {
Highlighter h = comp.getHighlighter();
h.removeAllHighlights();
String text = comp.getText().toUpperCase();
for (int j = 0; j < text.length(); j += 1) {
char ch = text.charAt(j);
if (charsToHighlight.indexOf(ch) >= 0) {
try {
h.addHighlight(j, j + 1, DefaultHighlighter.DefaultPainter);
} catch (BadLocationException ble) {
}
}
}
}
public static void main(String args[]) {
final JFrame frame = new JFrame("MultiHighlight");
frame.add(new JTextField("Another focusable JComponents"), BorderLayout.NORTH);
JTextArea area = new JTextArea(10, 20);
area.setText("This is the story\nof the hare who\nlost his spectacles."
+ "\nThis is the story\nof the hare who\nlost his spectacles.");
frame.getContentPane().add(new JScrollPane(area), BorderLayout.CENTER);
JButton b = new JButton("Highlight All Vowels");
b.addActionListener(new MultiHighlight(area, "aeiouAEIOU"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(b, BorderLayout.SOUTH);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
frame.pack();
frame.setVisible(true);
}
});
}
}
I'm trying to create an Onscreen telepad where people can press the keypad buttons and itll come up in the text box I haven't made the ActionListner for the keypad yet but I want it to show up in the view... Here's the code for the Keypad Panel and the View there is also a duration timer which I've managed to get working but can't put them into one view
Here's the Keypad Panel
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
public class KeypadPanel extends JPanel {
private JButton noStar;
private JButton noHash;
private JButton[] buttons;
private JButton C;
private JButton add;
private JPanel keypadPanel;
public KeypadPanel(TelepadController controller) {
buttons = new JButton[10];
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton("" + i);
// buttons[i].addActionListener(controller.new NumberButtonListener());
}
//noStar.addActionListener(controller.new noStarActionListener);
//noHash.addActionListener(controller.new noHashActionListener);
//C.addActionListener(controller.new CActionListener);
//add.addActionListener(controller.new addActionListener);
noStar = new JButton("*");
noHash = new JButton("#");
C = new JButton("C");
add = new JButton("+");
JPanel keypadPanel = new JPanel();
keypadPanel.setLayout(new GridLayout(4, 3));
for (int i = 1; i <= 9; i++) {
keypadPanel.add(buttons[i]);
add(noStar);
add(noHash);
add(C);
add(add);
}
}
}
And here's the code for the main View
package londontelepad2;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.FontUIResource;
import org.apache.commons.beanutils.BeanUtils;
public class TelepadView implements Observer {
private StopwatchPanel stopwatchPanel;
private KeypadPanel keypadPanel;
private JFrame frame;
/**
*
* #param controller
*/
public TelepadView(TelepadController controller) {
super();
this.setResources();
frame = new JFrame("London Telepad");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
stopwatchPanel = new StopwatchPanel(controller);
//stopwatchPanel = new StopwatchPanel2(controller);
keypadPanel = new KeypadPanel(controller);
frame.getContentPane().add(stopwatchPanel);
frame.getContentPane().add(keypadPanel);
frame.pack();
}
public void show() {
frame.setVisible(true);
}
#Override
public void update(Observable observable, Object arg) {
if (arg.equals(Properties.TIME)) {
try {
stopwatchPanel.setTime(BeanUtils.getProperty(observable,
Properties.TIME));
} catch (Exception e) {
System.out.println(e);
}
}
}
public void setResetState() {
stopwatchPanel.setButtons(true, false, false);
}
public void setStoppedState() {
stopwatchPanel.setButtons(false, false, true);
}
public void setRunningState() {
stopwatchPanel.setButtons(false, true, false);
}
private void setResources() {
ColorUIResource defaultBackground = new ColorUIResource(Color.white);
ColorUIResource defaultForeground = new ColorUIResource(Color.black);
ColorUIResource disabledColor = new ColorUIResource(Color.lightGray);
FontUIResource smallFont = new FontUIResource(
new Font("Dialog", Font.BOLD, 12));
FontUIResource bigFont = new FontUIResource(
new Font("Dialog", Font.BOLD, 14));
UIManager.put("Button.background",
defaultBackground);
UIManager.put("Button.foreground",
defaultForeground);
UIManager.put("Button.disabledText",
disabledColor);
UIManager.put("Button.font", smallFont);
UIManager.put("Label.background",
defaultBackground);
UIManager.put("Label.foreground",
defaultForeground);
UIManager.put("Label.font", bigFont);
UIManager.put("Panel.background",
defaultBackground);
UIManager.put("Panel.foreground",
defaultForeground);
}
}
If I do the .add seperately I get an error to do with (actual and formal argument lists differ in length)
and if i do it together I get java.lang.IllegalArgumentException: cannot add to layout: constraint must be a string (or null)
And I can't find what it is im doing wrong!!
All the help in the world would be very appreciated seeing as I'm an Uber noob at java!
Thank you
Bilal
UPDATE
Here's a log of the error I reciveve when I put them in the same .add field
Exception in thread "main" java.lang.NullPointerException
at londontelepad2.KeypadPanel.<init>(KeypadPanel.java:48)
at londontelepad2.TelepadView.<init>(TelepadView.java:46)
at londontelepad2.TelepadController.<init>(TelepadController.java:33)
at londontelepad2.LondonTelepad2.main(LondonTelepad2.java:19)
Java Result: 1
Wait, KeypadPanel is just a plain object. Why doesn't it extend JPanel?
you are calling the add()-method of a JFrame to add your components to the frame? You need to call
frame.getContentPane().add(comp);