Could you help me understand how to set left vertical alignment to the checkboxes. I mean each checkbox on its own row.
Tried everything I could imagine and have come to the end of my wit.
public class DisplayFrame extends JFrame {
public DisplayFrame(ArrayList<String> contents){
DisplayPanel panel = new DisplayPanel(contents, whiteList);
add(panel);
}
private void displayAll(){
DisplayFrame frame = new DisplayFrame(contents, whiteList);
GridBagLayout gbl = new GridBagLayout();
frame.setLayout(gbl);
frame.setVisible(true);
...
}
public class DisplayPanel extends JPanel {
ArrayList<JCheckBox> cbArrayList = new ArrayList<JCheckBox>();
ArrayList<String> contents;
...
public DisplayPanel(ArrayList<String> contents){
...
createListOfCheckBoxes();
}
private void createListOfCheckBoxes() {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = contents.size() + 1;
gbc.gridheight = contents.size() + 1;
for (int i = 0; i < contents.size(); i++){
gbc.gridx = 0;
gbc.gridy = i;
String configuration = contents.get(i);
JCheckBox currentCheckBox = new JCheckBox(configuration);
if (whiteList.contains(configuration)){
currentCheckBox.setSelected(true);
}
currentCheckBox.setVisible(true);
add(currentCheckBox, gbc);
}
}
"If I were able to proceed without GridBagLayout, that would suit me"
You can just use a BoxLayout. Box is a convenience class for BoxLayout. You can just do
Box box = Box.createVerticalBox();
for (int i = 0; i < contents.size(); i++){
String configuration = contents.get(i);
JCheckBox currentCheckBox = new JCheckBox(configuration);
if (whiteList.contains(configuration)){
currentCheckBox.setSelected(true);
}
box.add(currentCheckBox);
}
Since Box is a JComponent, you can just add the box to a container.
You can see more at How to Use BoxLayout
Simple Example
import javax.swing.*;
public class BoxDemo {
public static void main(String[] args) {
Box box = Box.createVerticalBox();
JCheckBox cbox1 = new JCheckBox("Check me once");
JCheckBox cbox2 = new JCheckBox("Check me twice");
JCheckBox cbox3 = new JCheckBox("Check me thrice");
box.add(cbox1);
box.add(cbox2);
box.add(cbox3);
JOptionPane.showMessageDialog(null, box);
}
}
Related
What I am after is I would like for whenever someone checks a checkbox, the text for which the box they selected is output to the right panel(I have a split pane). Right now it is not responding so I don't think my BoxHandler is working properly(implements ItemListener). My function addBoxListeners is supposed to add item listeners for each checkbox that I have and the function I overrode in BoxHandler, function itemStateChanged should add text to the right panel, and I know that addText is working because I tested it outside of the itemListener stuff.
void addText(String s) { // adds text to the right panel, adds string s
JLabel temp = new JLabel();
temp.setText(s);
temp.setBorder(border1);
rightPanel.add(temp);
}
void addBoxes() {
int i = 0;
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (i = 0; i < 10; i++) {
JCheckBox tempBox = new JCheckBox("word " + i);
boxes.add(tempBox);
leftPanel.add(tempBox, gbc);
//leftPanel.add(new JCheckBox("word" + i), gbc);
}
}
private class BoxHandler implements ItemListener{
public void itemStateChanged(ItemEvent event) {
for (JCheckBox checkBox : boxes) {
if (checkBox.isSelected() ) {
addText(checkBox.getText());
}
}
}
}
void addBoxListeners() { // add listeners to all the boxes in the arraylist
BoxHandler handler = new BoxHandler();
int i = 0;
for ( i = 0; i < boxes.size(); i++) {
boxes.get(i).addItemListener(handler);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
CheckBox2 cb = new CheckBox2();
cb.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
cb.pack();
cb.setLocationRelativeTo(null);
cb.addBoxListeners();
cb.setVisible(true);
}
Below is part of my class declaration:
public class CheckBox2 extends JFrame {
private ArrayList<JCheckBox> boxes = new ArrayList<JCheckBox>();
JSplitPane splitPane;
EmptyBorder border1 = new EmptyBorder(5, 5, 5, 5);
private JPanel leftPanel = new JPanel();
private JPanel rightPanel = new JPanel();
JLabel labelOne = new JLabel();
JLabel labelTwo = new JLabel();
...
I am working on a program that has no errors when I compile, and the logic runs soundly for it's purpose (I'm making a basic Penny Pitch program in GUI). The board is filled with image icons that contain the number of points a player will receive if they land on it, and when they land on a spot the image icon is suppose to switch to a picture of the same spot with a penny on it. However, when the previous icon is removed and the new "occupied" one is assigned, it is assigned at the end of the panel rather than the previous spot the "empty" icon was taken from.
To illustrate:
this is the normal layout,
before "tossing" a penny,
and this is the shifted layout,
after "tossing" a penny.
I can't find any sources explaining how to add a component to a panel in a spot previously occupied by a removed component. If anyone knows how, it would be great help!
-----------------------------------EDIT-----------------------------------------
New pictures:,.
I'm using a GridBagLayout now, and since I'm still not sure what is the cause of the new added component not taking the space of the removed one, I cut down my entire program to illustrate it's aspects:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class PennyPitch extends JFrame implements ItemListener{
//variables
int aa=0, thrown=0, place=0, illit=1, illit2=1;
Random pitch = new Random();
private ImageIcon full = new ImageIcon("pitchFull.png");
//map
private Map tossing;
//jbuttons
private JButton confirm = new JButton (new ImageIcon("pitchPenny.png"));
//map
private Map<Integer, ColorPanel> spot = new HashMap<Integer, ColorPanel>();
//declared icon to use when button is pushed
private ColorPanel rSet = new ColorPanel(Color.white, full);
//panel
private JPanel input = new JPanel(new GridBagLayout ());
private GridBagConstraints c = new GridBagConstraints();
public PennyPitch(){
prepareGUI();
}
public static void main(String[] args){
PennyPitch pitch = new PennyPitch(); }
private void prepareGUI(){
//background
input.setBackground(Color.WHITE);
//button design
confirm.setBorder(BorderFactory.createEmptyBorder());
confirm.setContentAreaFilled(false);
//icon for use
ImageIcon one = new ImageIcon("pitchOne.png");
//components for map
ColorPanel i1 = new ColorPanel(Color.white, one);
ColorPanel i2 = new ColorPanel(Color.white, one);
ColorPanel i3 = new ColorPanel(Color.white, one);
//MAP FOR THE STATS
spot.put(1, i1);
spot.put(2, i2);
spot.put(3, i3);
//PANEL
c.ipady = 50;
c.ipadx = 50;
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
input.add(spot.get(1),c);
c.ipady = 50;
c.ipadx = 50;
c.gridx = 2;
c.gridy = 1;
c.gridwidth = 1;
input.add(spot.get(2),c);
c.ipady = 50;
c.ipadx = 50;
c.gridx = 3;
c.gridy = 1;
c.gridwidth = 1;
input.add(spot.get(3),c);
c.ipady = 50;
c.ipadx = 50;
c.gridx = 4;
c.gridy = 1;
c.gridwidth = 2;
input.add(confirm,c);
//listener for button
confirm.addActionListener (new AddListener());
//CONTAINER
Container container = getContentPane();
container.add(input);
//frame information
Toolkit tk = Toolkit.getDefaultToolkit();
setSize(600, 600);
setTitle("PENNY PITCH");
setMinimumSize(new Dimension(600,600));
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack ();
setVisible(true);
}
private class AddListener implements ActionListener {
public void actionPerformed(ActionEvent a){
if (a.getSource()== confirm) {
//generates number to land on
thrown = pitch.nextInt(3) + 1;
System.out.println(thrown);
place=illit;
spot.put(place, rSet);
Component old = input.getComponent(thrown);
Component newn = input.getComponent(place);
Component[] compSet=input.getComponents();
for(int i=0; i<compSet.length; i++){
if(old.equals(compSet[i])) {
input.remove(old);
c.ipady = 50;
c.ipadx = 50;
c.gridwidth = 1;
input.add(newn, i);
}
}
illit++;
repaint();
}
}
}
public void itemStateChanged(ItemEvent e) {
System.out.println (aa);
}
}
class ImageLabel extends JLabel {
public ImageLabel (String img){
this (new ImageIcon (img));
}
public ImageLabel (ImageIcon icon){
setIcon(icon);
setIconTextGap(0);
setBorder(null);
setText(null);
setSize(icon.getImage().getWidth(null),icon.getImage().getHeight(null));
}
}
Container has a method getComponents(). JPanel is a descendant and will hopefully have it. To check for a given component you do the following:
Component[] cmp=myPanel.getComponents();
for(int i=0; i<cmp.length; i++)
if(myComponent.equals(cmp[i])) {
myPanel.remove(myComponent);
myPanel.add(myNewComponent, i);
}
where myComponent is the component you want to remove and myNewComponent is the component you want to add.
--
Ok your code uses some ColorPanel which I'm not familiar with but lets suppose its something like a JLabel.
I understand that you actually add (in the full code) as many colorpanels as coins in the image.
GridBag is out of my consideration - but maybe you should just skip the ipadx etc and just remove/add. Better yet use some /normal/ layout such as GridLayout or even FlowLayout for testing purposes.
Suggestion: have a JPanel (input) with a GridLayout(5, 5) where you add only the color panels (numbers). Have another JPanel (jp2) where you add the previous JPanel (input) and the button(confirm) - this jp2 is added to the jframe. You should add/remove on the input.
for(i=0; i<25; i++) input.add(new ColorPanel(...));
thrown = pitch.nextInt(25);
System.out.println(thrown);
place=illit;
spot.put(place, rSet);
input.remove(thrown);
Component newn = input.getComponent(place);
input.add(newn, thrown);
Also make sure you call validate after each removal/addition:
input.validate();
In summary, the following is a simplified working program of what you are trying to do:
class T extends Frame {
public T() {
setSize(500, 500);
setLayout(new GridLayout(5, 5));
for(int i=0; i<25; i++) add(new Label(""+i));
setVisible(true);
}
public static void main(String args[]) {
T t=new T();
for(int i=0; i<5; i++) {
int r=(int)(Math.random()*25);
t.remove(r);
t.add(new Label(""+(i+1)), r);
t.validate();
t.repaint();
try { Thread.sleep(5000); } catch(InterruptedException ie) {}
}
}
}
My school project is to create a purchasing system for that I create a JPanel array to list out all the products information and also allow user to input something for every item. And I dont know how to get all the values from jtextfields by clicking one button. The actionPerformed() method always requires a final variable which is quite troublesome for me.
private JButton payBtn;
public void shoppingCartTab(Customer userIn){
contentPanel.removeAll();
bottomPanel.removeAll();
final Customer USER = userIn;
ArrayList<Product> pArray = new ArrayList<Product>();
pArray = loadCartFile.loadCartFile(userIn);
JLabel tabLabel = new JLabel("Shopping Cart");
JPanel cartItems = new JPanel();
cartItems.setLayout(new BoxLayout(cartItems, BoxLayout.Y_AXIS));
final JPanel CONSTANT_CART = cartItems;
JScrollPane scroller = new JScrollPane(cartItems);
if(pArray != null){
JPanel item[] = new JPanel[pArray.size()];
for(int i = 0; i< pArray.size(); i++){
item[i] = new JPanel();
final JPanel JPANEL_TO_DEL = item[i];
item[i].setLayout(new GridBagLayout());
GridBagConstraints gBC = new GridBagConstraints();
gBC.weightx = 0.3;
item[i].setBorder(BorderFactory.createLineBorder(Color.BLACK));
JLabel icon_small = new JLabel(new ImageIcon("Icons\\" + pArray.get(i).getID() + "_small.jpg"));
JLabel itemID = new JLabel(pArray.get(i).getID());
final String CONSTANT_ID = pArray.get(i).getID();
JLabel itemName = new JLabel(pArray.get(i).getName());
JLabel itemPrice = new JLabel("$" + pArray.get(i).getPrice());
JPanel setQuantity = new JPanel();
JButton plusBtn = new JButton("+");plusBtn.setPreferredSize(new Dimension(45,30));
final JTextField QUANTITY = new JTextField("0");QUANTITY.setColumns(3);
QUANTITY.setPreferredSize(new Dimension(45,30));QUANTITY.setHorizontalAlignment(JTextField.CENTER);
JButton minusBtn = new JButton("-");minusBtn.setPreferredSize(new Dimension(45,30));
plusBtn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent event){
if(Integer.parseInt(QUANTITY.getText())<100)
QUANTITY.setText(Integer.toString(Integer.parseInt(QUANTITY.getText())+1));
}
});
minusBtn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent event){
if(Integer.parseInt(QUANTITY.getText())>0)
QUANTITY.setText(Integer.toString(Integer.parseInt(QUANTITY.getText())-1));
}
});
setQuantity.add(plusBtn);
setQuantity.add(QUANTITY);
setQuantity.add(minusBtn);
JButton delBtn = new JButton("Delete");
delBtn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent event){
int dialogResult = JOptionPane.showConfirmDialog(null, "Are you sure to remove this item from your cart?", "Confirm", JOptionPane.YES_NO_OPTION);
if(dialogResult == JOptionPane.YES_OPTION){
CONSTANT_CART.remove(JPANEL_TO_DEL);
revalidate();
repaint();
ShoppingCart.removeItem(USER, CONSTANT_ID);
}
}
});
gBC.gridx = 0;
gBC.gridy = 0;
item[i].add(icon_small,gBC);
gBC.gridx = 1;
gBC.gridy = 0;
item[i].add(itemID,gBC);
gBC.gridx = 2;
gBC.gridy = 0;
item[i].add(itemName,gBC);
gBC.gridx = 3;
gBC.gridy = 0;
item[i].add(itemPrice,gBC);
gBC.gridx = 4;
gBC.gridy = 0;
item[i].add(setQuantity,gBC);
gBC.gridx = 5;
gBC.gridy = 0;
item[i].add(delBtn,gBC);
cartItems.add(item[i]);
}
contentPanel.add(tabLabel);
contentPanel.add(scroller);
payBtn = new JButton("Pay");
bottomPanel.add(payBtn); payBtn.addActionListener(this);
}else{
JLabel emptyMsg = new JLabel("Your cart is empty!");
contentPanel.add(emptyMsg);
}
revalidate();
repaint();
}
One solution would be to create a type which extends JPanel, and exposes a public property, which when called returns the value stored in the JTextField. Something like:
public class TextFieldPanel extends JPanel {
private JTextField myTextField;
public TextFieldPanel()
{
//layout init code here
}
public String getText()
{
return myTextField.getText();
}
}
Then just use this class instead of a regular JPanel. Then when your button is clicked, iterate over each of the objects in your collection, and call getText() on them to get your values.
I want the various components to spread out and fill the entire window.
Have you tried anything else? Yes, I tried GridLayout but then the buttons look huge. I also tried pack() which made the window small instead. The window should be 750x750 :)
What I was trying is this:
These 4 buttons on the top as a thin strip
The scroll pane with JPanels inside which will contain all the video conversion tasks. This takes up the maximum space
A JPanel at the bottom containing a JProgressBar as a thin strip.
But something seems to have messed up somewhere. Please help me solve this
SSCCE
import java.awt.*;
import javax.swing.*;
import com.explodingpixels.macwidgets.*;
public class HudTest {
public static void main(String[] args) {
HudWindow hud = new HudWindow("Window");
hud.getJDialog().setSize(750, 750);
hud.getJDialog().setLocationRelativeTo(null);
hud.getJDialog().setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel buttonPanel = new JPanel(new FlowLayout());
JButton addVideo = HudWidgetFactory.createHudButton("Add New Video");
JButton removeVideo = HudWidgetFactory.createHudButton("Remove Video");
JButton startAll = HudWidgetFactory.createHudButton("Start All Tasks");
JButton stopAll = HudWidgetFactory.createHudButton("Stop All Tasks");
buttonPanel.add(addVideo);
buttonPanel.add(startAll);
buttonPanel.add(removeVideo);
buttonPanel.add(stopAll);
JPanel taskPanel = new JPanel(new GridLayout(0,1));
JScrollPane taskScrollPane = new JScrollPane(taskPanel);
IAppWidgetFactory.makeIAppScrollPane(taskScrollPane);
for(int i=0;i<10;i++){
ColorPanel c = new ColorPanel();
c.setPreferredSize(new Dimension(750,100));
taskPanel.add(c);
}
JPanel progressBarPanel = new JPanel();
JComponent component = (JComponent) hud.getContentPane();
component.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
Insets in = new Insets(2,2,2,2);
gbc.insets = in;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 10;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
component.add(buttonPanel,gbc);
gbc.gridy += 1;
gbc.gridheight = 17;
component.add(taskScrollPane,gbc);
gbc.gridy += 17;
gbc.gridheight = 2;
component.add(progressBarPanel,gbc);
hud.getJDialog().setVisible(true);
}
}
Use this
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridbagConstraints.BOTH
Why not simply place three JPanels on top of one JPanel with BorderLayout as Layout Manager, where the middle JPanel with all custom panels with their respective sizes can be accommodated inside a JScrollPane, as shown in the below example :
import javax.swing.*;
import java.awt.*;
import java.util.Random;
/**
* Created with IntelliJ IDEA.
* User: Gagandeep Bali
* Date: 5/17/13
* Time: 6:09 PM
* To change this template use File | Settings | File Templates.
*/
public class PlayerBase
{
private JPanel contentPane;
private JPanel buttonPanel;
private JPanel centerPanel;
private CustomPanel[] colourPanel;
private JPanel progressPanel;
private JButton addVideoButton;
private JButton removeVideoButton;
private JButton startAllButton;
private JButton stopAllButton;
private JProgressBar progressBar;
private Random random;
public PlayerBase()
{
colourPanel = new CustomPanel[10];
random = new Random();
}
private void displayGUI()
{
JFrame playerWindow = new JFrame("Player Window");
playerWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel(new BorderLayout(5, 5));
contentPane.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
addVideoButton = new JButton("Add New Video");
removeVideoButton = new JButton("Remove Video");
startAllButton = new JButton("Start all tasks");
stopAllButton = new JButton("Stop all tasks");
buttonPanel.add(addVideoButton);
buttonPanel.add(removeVideoButton);
buttonPanel.add(startAllButton);
buttonPanel.add(stopAllButton);
contentPane.add(buttonPanel, BorderLayout.PAGE_START);
JScrollPane scroller = new JScrollPane();
centerPanel = new JPanel(new GridLayout(0, 1, 2, 2));
for (int i = 0; i < colourPanel.length; i++)
{
colourPanel[i] = new CustomPanel(new Color(
random.nextInt(255), random.nextInt(255)
, random.nextInt(255)));
centerPanel.add(colourPanel[i]);
}
scroller.setViewportView(centerPanel);
contentPane.add(scroller, BorderLayout.CENTER);
progressPanel = new JPanel(new BorderLayout(5, 5));
progressBar = new JProgressBar(SwingConstants.HORIZONTAL);
progressPanel.add(progressBar);
contentPane.add(progressPanel, BorderLayout.PAGE_END);
playerWindow.setContentPane(contentPane);
playerWindow.pack();
//playerWindow.setSize(750, 750);
playerWindow.setLocationByPlatform(true);
playerWindow.setVisible(true);
}
public static void main(String[] args)
{
Runnable runnable = new Runnable()
{
#Override
public void run()
{
new PlayerBase().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
class CustomPanel extends JPanel
{
public CustomPanel(Color backGroundColour)
{
setOpaque(true);
setBackground(backGroundColour);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(750, 100));
}
}
OUTPUT :
I've a positioning problem with the GridBagLayout :
I try to place in center (at the top) a label but with my code (for a reason which I didn't see), I've this :
I want that the label Test are at the top of my window and in center. Someone can explain me the reason of this bad positionnement ?
My program :
public class Accueil extends JFrame {
private JPanel home = new JPanel();
private GridBagConstraints grille = new GridBagConstraints();
private JLabel title = new JLabel("Test");
public Accueil() {
home.setLayout(new GridLayout());
init_grille();
init_title();
this.add(home);
this.setSize(600,600);
this.setTitle("Test One");
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
private void init_grille() {
grille.fill = GridBagConstraints.BOTH;
grille.weightx = 2;
grille.weighty = 5;
grille.ipady=grille.anchor=GridBagConstraints.CENTER;;
}
private void init_title() {
grille.fill = GridBagConstraints.HORIZONTAL;
grille.gridx = 0;
grille.gridy = 0;
home.add(title,grille);
}
public static void main(String [] args) {
new Accueil();
}
}
This won't help:
home.setLayout(new GridLayout());
You probably want:
home.setLayout(new GridBagLayout());
Also, these changes should work:
private void init_title() {
grille.fill = GridBagConstraints.NONE;
grille.gridx = 0;
grille.gridy = 0;
grille.anchor = GridBagConstraints.NORTH;
home.add(title,grille);
}