Dynamic JPanel with objects not displaying - java

Can someone take a look at this part of my code and tell me why it won't return the objects inside the JPanel? It definitely goes inside the loop since I tried printing statements inside. Also this JPanel object is being put inside a TabbedPane just for clarification. Let me know if I need to explain in more detail or show more code to find a solution. Thanks.
JPanel createTipTailoringPanel(TipCalcModel model)
{
JPanel content = new JPanel();
int size = model.getNumOfPeople();
content.removeAll();
content.updateUI();
content.setLayout(new GridLayout(0,4));
JTextField text[] = new JTextField[size];
JSlider slider[] = new JSlider[size];
JLabel label[] = new JLabel[size];
JLabel cash[] = new JLabel[size];
if(size == 0)
{
return content;
}
else
{
for(int i=0; i<size; i++)
{
text[i] = new JTextField();
slider[i] = new JSlider();
label[i] = new JLabel("$");
cash[i] = new JLabel();
content.add(text[i]);
content.add(slider[i]);
content.add(label[i]);
content.add(cash[i]);
}
return content;
}
}
Here is my calling method and the actionlistener that I use to pass in the numberofpeople:
TipCalcView(TipCalcModel model)
{
setTitle("Tip Calculator");
JTabbedPane tabbedPane = new JTabbedPane();
getContentPane().add(tabbedPane);
tabbedPane.addTab("Main Menu", createMainPanel());
tabbedPane.setSelectedIndex(0);
tabbedPane.addTab("Tip Tailoring", createTipTailoringPanel(model));
tabbedPane.addTab("Config Panel", createConfigPanel());
}
class GuestsListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
int userInput = 0;
try{
userInput = m_view.getGuests();
m_model.setNumOfPeople(userInput);
m_view.createTipTailoringPanel(m_model);
}
catch(NumberFormatException nfex)
{
m_view.showError("Bad input: '" + userInput + "'");
}
}
}

I suspect that your problem is outside of the code you listed. Here's a simplified working example:
public static void main(String[] args) {
JFrame frame = new JFrame();
DynamicJPanel dynamic = new DynamicJPanel();
frame.add(dynamic.createTipTailoringPanel(3));
frame.pack();
frame.setVisible(true);
}
JPanel createTipTailoringPanel(int size) {
JPanel content = new JPanel();
content.setLayout(new GridLayout(0, 4));
for (int i = 0; i < size; i++) {
content.add(new JTextField());
content.add(new JSlider());
content.add(new JLabel("$"));
content.add(new JLabel());
}
return content;
}

First, since you don't use the arrays anywhere, it could be shortened to:
JPanel createTipTailoringPanel(TipCalcModel model)
{
JPanel content = new JPanel();
int size = model.getNumOfPeople();
content.setLayout(new GridLayout(0,4));
if(size == 0)
{
return content;
}
else
{
for(int i=0; i<size; i++)
{
content.add(new JTextField());
content.add(new JSlider());
content.add(new JLabel("$"));
content.add(new JLabel());
}
return content;
}
}
Second, seems like you add an empty components to the panel, maybe that's what you actually get?
Third, add you need to add the content panel to the JFrame (or other container) once it returns from the method above.

Related

Having Multiple JButtons

sorry for the simple question, but I'm really new to this and can't really find an answer. I'm confused on how to add two (or more) JButtons. I can't seem to get both to show, only one ever shows, which is the "Division" one.
My most recent attempt is below. How can I get both buttons to show at the button of the window?
public class Calculator implements ActionListener {
private JFrame frame;
private JTextField xfield, yfield;
private JLabel result;
private JButton subtractButton;
private JButton divideButton;
private JPanel xpanel;
public Calculator() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
xpanel = new JPanel();
xpanel.setLayout(new GridLayout(3,2));
xpanel.add(new JLabel("x:"));
xfield = new JTextField("0", 5);
xpanel.add(xfield);
xpanel.add(new JLabel("y:"));
yfield = new JTextField("0", 5);
xpanel.add(yfield);
xpanel.add(new JLabel("x*y="));
result = new JLabel("0");
xpanel.add(result);
frame.add(xpanel, BorderLayout.NORTH);
subtractButton = new JButton("Subtract");
frame.add(subtractButton, BorderLayout.SOUTH);
subtractButton.addActionListener(this);
divideButton = new JButton("Division");
frame.add(divideButton, BorderLayout.SOUTH);
divideButton.addActionListener(this);
frame.pack();
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent event) {
int x = 0;
int y = 0;
String xText = xfield.getText();
String yText = yfield.getText();
try {
x = Integer.parseInt(xText);
}
catch (NumberFormatException e) {
x = 0;
}
try {
y = Integer.parseInt(yText);
}
catch (NumberFormatException e) {
y = 0;
}
result.setText(Integer.toString(x-y));
}
}
You need to add both buttons in a JPanel before adding that JPanel in the SOUTH of your frame.
So instead of
subtractButton = new JButton("Subtract");
frame.add(subtractButton, BorderLayout.SOUTH);
subtractButton.addActionListener(this);
divideButton = new JButton("Division");
frame.add(divideButton, BorderLayout.SOUTH);
divideButton.addActionListener(this);
You can do this
JPanel southPanel = new JPanel();
subtractButton = new JButton("Subtract");
southPanel.add(subtractButton);
subtractButton.addActionListener(this);
divideButton = new JButton("Division");
southPanel.add(divideButton);
divideButton.addActionListener(this);
frame.add(southPanel , BorderLayout.SOUTH);
Use Eclipse and WindowBuilder for your Swing interfaces and add as many buttons as you like or move them around with your mouse. Its much easier especially if you are new to this and you'll learn a lot from the generated code.

How to show a list in JFrame/JPanel and refresh it after button click?

I don't have an idea how to show my list of objects (regardless of parameters) one by one in JFrame. I would like to use a loop for doing it. I want to show first 10 elements and next 10 elements after button click etc. Any ideas?
i think it wouldn't work for me... i've added a list in JList to a JPanel and after button click it refreshes at all but when i click on actually showed JList elements their are coming back to the first ones - to the beginning... (the repaint() command is commented because with it i don't see any changes of my JList). these same effect i have when remove() and revalidate() commands are also commented... so i don't know where the problem is...
public Window()
{
setTitle("Window");
setSize(600,600);
setResizable(false);
setLocationRelativeTo(null);
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
JList<?> list = new JList<Object>(tmp_list.toArray());
listPanel = new JPanel();
listPanel.setLayout(new BorderLayout());
listPanel.add(new JScrollPane(list));
add(listPanel, BorderLayout.CENTER);
nextButton = new JButton("Next");
buttonsPanel = new JPanel();
buttonsPanel.setLayout(new FlowLayout());
buttonsPanel.add(nextButton);
add(buttonsPanel, BorderLayout.SOUTH);
nextButton.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
if(source == nextButton)
{
if(current_page < last_page)
{
current_page++;
refreshListPanel();
}
}
}
private void refreshListPanel()
{
listPanel.removeAll();
tmp_list = showCurrentPage(N, cars1);
JList<?> list = new JList<Object>(tmp_list.toArray());
listPanel.add(new JScrollPane(list));
listPanel.revalidate();
listPanel.repaint();
}
private List<Car> showCurrentPage(int n, List<Car> main_list)
{
List<Car> list = new ArrayList<Car>();
int counter = n*(current_page);
int size;
if(current_page == last_page && C%N != 0)
size = main_list.size()%n;
else
size = n;
for(int i = 0; i < size; i++)
{
list.add(main_list.get(counter + i));
}
return list;
}

create Jbuttons from ActionListener variable

the mission here is to create JButtons from a String in ActionListener, but we need a way to refresh the GUI panel so it know that there is now variable for the button creater in the GUI. i have a feeling that the button creater must be in ActionListener and there is a command like repaint() or removeAll that is missing inside the ActionListener.
public JButton[] turneringer = null;
JButton AntallTurneringer = new JButton("number of buttons");
JMenuBar meny = new JMenuBar();
JMenu fil = new JMenu("somthing");
JMenuItem angre = new JMenuItem("deleate on button");
JMenuItem angre2 = new JMenuItem("deleate all buttons");
int d;
int i;
public GUI(){
this.setTitle("somthing");
this.setSize(500,500);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());
this.setJMenuBar(meny);
meny.add(fil);
fil.add(angre2);
fil.add(angre);
angre2.addActionListener(this);
angre.addActionListener(this);
AntallTurneringer.addActionListener(this);
this.add(AntallTurneringer);
AntallTurneringer.setVisible(true);
if(d > 0){
turneringer = new JButton[d];
for(i = 0; i < d; i++){
turneringer[d] = new JButton();
turneringer[d].addActionListener(this);
turneringer[d].setText("Turnering "+(i+1));
turneringer[d].setVisible(true);
this.add(turneringer[d]);
}}
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent arg0) {
if(arg0.getSource().equals(AntallTurneringer)){
String tu = JOptionPane.showInputDialog(null, "number of buttons");
d = Integer.parseInt(tu);
}
}
You could use a separate panel for the buttons. would simplify the whole thing.
private JPanel buttonPnl;
public void actionPerformed(ActionEvent e){
buttonPnl.invalidate();
buttonPnl.clear();
//create the new buttons
buttonPnl.validate();
buttonPnl.repaint();
}
I have solved it, it were no need for repainting or clearing anything. the first problem in the code were that i had used [d] inside the array, and not[i]. the second problem were the placement of the for loop. this is the working code under.
public JButton[] turneringer = null;
JButton AntallTurneringer = new JButton("Velg antall turneringer");
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
int d;
public GUI(){
this.setTitle("Squash Turnering");
this.setLayout(new GridLayout());
this.setSize(500,500);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
panel1.setBackground(Color.BLACK);
panel2.setBackground(Color.RED);
AntallTurneringer.addActionListener(this);
AntallTurneringer.setVisible(true);
panel1.add(AntallTurneringer);
add(panel1);
add(panel2);
panel2.setVisible(false);
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent arg0) {
if(arg0.getSource().equals(AntallTurneringer)){
String tu = JOptionPane.showInputDialog(null, "number of buttons you want to add");
d = Integer.parseInt(tu);
turneringer = new JButton[d];
for(int i = 0; i < d; i++){
turneringer[i] = new JButton();
turneringer[i].addActionListener(this);
turneringer[i].setText("Turnering "+(i+1));
turneringer[i].setVisible(true);
turneringer[i].setSize(100, 100);
panel2.add(turneringer[i]);
}
panel1.setVisible(false);
panel2.setVisible(true);
}
}}

Need help debugging, code compiles but won't run

Hey I could use help debugging this program. The code is not mine, it is from an answer to a question and I wanted to try it but I get a NullPointerException and can't figure out where the problem is. I think the problem may be image paths but I am not sure so I could use help.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
public class CircleImages {
private int score = 0;
private JTextField scoreField = new JTextField(10);
public CircleImages() {
scoreField.setEditable(false);
final ImageIcon[] icons = createImageIcons();
final JPanel iconPanel = createPanel(icons, 8);
JPanel bottomLeftPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
bottomLeftPanel.add(new JLabel("Score: "));
bottomLeftPanel.add(scoreField);
JPanel bottomRightPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
JButton newGame = new JButton("New Game");
bottomRightPanel.add(newGame);
JButton quit = new JButton("Quit");
bottomRightPanel.add(quit);
JPanel bottomPanel = new JPanel(new GridLayout(1, 2));
bottomPanel.add(bottomLeftPanel);
bottomPanel.add(bottomRightPanel);
newGame.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
reset(iconPanel, icons);
score = 0;
scoreField.setText(String.valueOf(score));
}
});
JFrame frame = new JFrame();
frame.add(iconPanel);
frame.add(bottomPanel, BorderLayout.PAGE_END);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void reset(JPanel panel, ImageIcon[] icons) {
Component[] comps = panel.getComponents();
Random random = new Random();
for(Component c : comps) {
if (c instanceof JLabel) {
JLabel button = (JLabel)c;
int index = random.nextInt(icons.length);
button.setIcon(icons[index]);
}
}
}
private JPanel createPanel(ImageIcon[] icons, int gridSize) {
Random random = new Random();
JPanel panel = new JPanel(new GridLayout(gridSize, gridSize));
for (int i = 0; i < gridSize * gridSize; i++) {
int index = random.nextInt(icons.length);
JLabel label = new JLabel(icons[index]);
label.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
score += 1;
scoreField.setText(String.valueOf(score));
}
});
label.setBorder(new LineBorder(Color.GRAY, 2));
panel.add(label);
}
return panel;
}
private ImageIcon[] createImageIcons() {
String[] files = {"DarkGrayButton.png",
"BlueButton.png",
"GreenButton.png",
"LightGrayButton.png",
"OrangeButton.png",
"RedButton.png",
"YellowButton.png"
};
ImageIcon[] icons = new ImageIcon[files.length];
for (int i = 0; i < files.length; i++) {
icons[i] = new ImageIcon(getClass().getResource("/circleimages/" + files[i]));
}
return icons;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new CircleImages();
}
});
}
}
Your problem is here:
icons[i] = new ImageIcon(getClass().getResource("/circleimages/" + files[i]));
You don't have the required images in your project, so getClass().getResource() will return null and you will have a NullPointerException in the constructor of ImageIcon.
What you have to do is put the following files in your project:
/circleimages/DarkGrayButton.png
/circleimages/BlueButton.png
/circleimages/GreenButton.png
/circleimages/LightGrayButton.png
/circleimages/OrangeButton.png
/circleimages/RedButton.png
/circleimages/YellowButton.png

Adding JPanels to JPanel array

I have declared an array:
private javax.swing.JPanel[] panelArray = new javax.swing.JPanel[3];
I also have 3 panels: panel0, panel1 and panel2. Can I add these panels to the array? i.e
panelArray[0] = panel0;
panelArray[1] = panel1;
panelArray[2] = panel2;
And then manipulate the arrays like this?
boolean[] myBools; .... then set them as true/false
for(int i=0; i<3; i++)
{
if(myBools[i])
panelArray[i].setVisible(true)
}
Because that does not work for me
On my side it's working fine, in this program :
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class MyPanel
{
private JPanel[] panelArray = new JPanel[3];
private boolean[] myBools = new boolean[]{false, false, false};
private int counter = 0;
private int prvPanelCounter = 0;
private Timer timer;
private ActionListener timerAction = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
counter++;
if (counter > 2)
counter = 0;
myBools[counter] = true;
for (int i = 0; i < 3; i++)
{
if (myBools[i])
{
panelArray[i].setVisible(myBools[i]);
panelArray[prvPanelCounter].setVisible(myBools[prvPanelCounter]);
myBools[i] = false;
prvPanelCounter = i;
break;
}
}
}
};
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Locate Mouse Position");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel0 = new JPanel();
panel0.setOpaque(true);
panel0.setBackground(Color.BLUE);
JPanel panel1 = new JPanel();
panel1.setOpaque(true);
panel1.setBackground(Color.RED);
JPanel panel2 = new JPanel();
panel2.setOpaque(true);
panel2.setBackground(Color.DARK_GRAY);
panelArray[0] = panel0;
panelArray[1] = panel1;
panelArray[2] = panel2;
JComponent contentPane = (JComponent) frame.getContentPane();
contentPane.setLayout(new GridLayout(0, 1));
frame.add(panel0);
frame.add(panel1);
frame.add(panel2);
panel0.setVisible(myBools[counter]);
panel1.setVisible(myBools[counter]);
panel2.setVisible(myBools[counter]);
frame.setSize(300, 300);
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, timerAction);
timer.start();
}
public static void main(String\u005B\u005D args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new MyPanel().createAndDisplayGUI();
}
});
}
}
What you want to do can be done, but here's a few points to bear in mind:
Make sure you initialise the JPanels before referencing them.
The statement "panelArray[i].setVisible(true)" needs a semicolon after it.
None of these panels will be visible unless you add them to another component, such as a JFrame.
Rather than state javax.swing.JPanel, you could just import the JPanel at the top of the page and refer to it as simply JPanel.
Your "if" statement is unnecessary. Just do .setVisible(myBools[i]);
Hope these were of some help to you.
Yes, you can. Did you really not initialize the myBools array with new ?

Categories