Swing: Placing group of components in a frame - swing

To be accurate and brief:
Is it possible to Layout a frame container with group of components(like check boxes, radio buttons, etc...) instead of adding them one by one to a frame? So, positioning them in a frame would be a lot more easier.
private void initializaUI(){
setSize(700, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Panel container to wrap checkboxes and radio buttons
JPanel panel = new JPanel(null);
JPanel checkBoxPanel = new JPanel(new BoxLayout(panel, defaultCloseOperation, null));
JPanel radioPanel_1 = new JPanel(new GridLayout());
JPanel radioPanel_2 = new JPanel(new GridLayout());
//Text field to display order
JTextField orderField = new JTextField(20);
orderField.setBounds(100, 100, 100, 20);
//Button to process place the order
JButton button = new JButton("Process Selection");
button.setBounds(300, 100, 100, 40);
//toppings check boxes
checkBoxPanel.setVisible(true);
checkBoxPanel.setBounds(100, 200, 100, 50);
String Topping[] = {"Tomato", "Green Pepper", "Black Olives", "Mushrooms", "Extra Cheese", "Pepperoni", "Sausage"};
checkBoxPanel.add(new JCheckBox("Tomato"));
checkBoxPanel.add(new JCheckBox(Topping[1]));
checkBoxPanel.add(new JCheckBox(Topping[2]));
checkBoxPanel.add(new JCheckBox(Topping[3]));
checkBoxPanel.add(new JCheckBox(Topping[4]));
checkBoxPanel.add(new JCheckBox(Topping[5]));
checkBoxPanel.add(new JCheckBox(Topping[6]));
//sizes radio buttons
String size[] = {"Small:$6.50", "Medium:$8.50", "Large:$10.00"};
JRadioButton radio = new JRadioButton(size[0]);
radio.setBounds(100, 50, 100, 20);
//
panel.add(checkBoxPanel);
//
setContentPane(panel);
This is the code which supposed to perform some actions based on user entry. please help me make it clear and readable.
This is the error: "The field Component.x is not visible"

Yes, that's what a JPanel is for. It's an empty container that has its inner layout manager and that can be placed wherever you want inside a JFrame (or inside another JPanel). So, just to give you an example you can have:
JPanel checkBoxPanel = new JPanel(new GridLayout(..));
JPanel fieldsPanel = new JPanel(new BoxLayout(..));
checkBoxPanel.add(new JCheckBox(..));
fieldsPanel.add(new JTextField(..));
frame.setLayout(new BorderLayout());
frame.add(checkBoxPanel, BorderLayout.NORTH);
frame.add(..)

Related

TextButton does not receive clicks in LibGDX

Here is my code:
public WelcomeScreen(final WallGame game) {
this.game = game;
// Setting up camera and viewport.
camera = new OrthographicCamera();
viewport = new StretchViewport(GAME_WORLD_WIDTH, GAME_WORLD_HEIGHT, camera);
viewport.apply();
stage = new Stage(viewport);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
Gdx.input.setInputProcessor(stage);
skin = new Skin(Gdx.files.internal("uiskin.json"));
skin.getFont("default-font").getData().setScale(0.1f, 0.1f);
backgroundTxtr = new Texture(Gdx.files.internal("background/background.png"));
background = new Image(backgroundTxtr);
background.setBounds(0, 0, GAME_WORLD_WIDTH, GAME_WORLD_HEIGHT);
final TextButton button = new TextButton("start", skin, "red-button");
button.setBounds(10, 10, 50, 50);
button.setTouchable(Touchable.enabled);
button.addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y) {
Gdx.app.log("AKS", "CLICKED");
}
});
final Dialog dialog = new Dialog("Click Message", skin);
dialog.setBounds(50, 50, 40, 40);
stage.addActor(background);
stage.addActor(button);
stage.addActor(dialog);
}
I can't seem to make the button work, I have an image to be shown when the button is clicked (the "down" attribute of the TextButton) but it doesn't change. What am I doing wrong?
I figured it out. I hadn't created a Table object to add the button into. It worked after I did that.

LibGDX: Skin and scaling problems

I'm trying to use Skins with TextButtons. However I'm having an issue where the TextureRegions of the Skin are NOT being scaled down to the tablesize.
This is leading to an issue like in this image:
As you can see that is the e from the word Hello. I managed to scale that down to a more reasonable size (still wrong). However the Button textures are still way too large.
Any ideas? Because I am pulling my hair out. I am using a custom viewport with a custom screenspace width and height. Here is the create method for the menu.
public void create(){
menuStage = new Stage();
camera = new OrthographicCamera();
viewPort = new StretchViewport(SCREEN_SPACE_WIDTH, SCREEN_SPACE_HEIGHT, camera);
viewPort.setWorldSize(SCREEN_SPACE_WIDTH, SCREEN_SPACE_HEIGHT);
menuStage.setViewport(viewPort);
devTexture = new Sprite (new Texture(Gdx.files.internal("data/16by9.png"), true));
Image newActor = new Image(devTexture.getTexture());
newActor.setSize(
viewPort.getWorldWidth(),
viewPort.getWorldHeight()
);
menuStage.addActor(newActor);
skin = new Skin(Gdx.files.internal("data/uiskin.json"));
menuTable = new Table();
skin.getFont("default-font").setScale(0.08f);
menuTable.debugAll();
menuTable.setFillParent(true);
TextButton a,b,c;
a = new TextButton("hello", skin);
b = new TextButton("hello", skin);
c = new TextButton("hello", skin);
a.getStyle().up.setMinWidth(2.0f);
b.getStyle().up.setMinHeight(2.0f);
b.getStyle().up.setMinWidth(2.0f);
c.getStyle().up.setMinHeight(2.0f);
c.getStyle().up.setMinWidth(2.0f);
menuTable.row();
menuTable.add(a).size(2.0f, 1.0f);
menuTable.add(b).size(2.0f, 1.0f);
menuTable.add(c).size(2.0f, 1.0f);
menuStage.addActor(menuTable);
camera.translate(
newActor.getWidth() / 2,
newActor.getHeight() / 2
);
}

GridBagLayouts in GridLayout

Trying to build about this GUI in Swing:
In my MainFrame i set a GridLayout like that to achieve 1 row, 2 columns:
setLayout(new GridLayout(1, 2));
In the Left Column i figures i would need a GridBagLayout as in the right column. Normal GridLayout doesn't work anymore because i want different sizes of each row. For the left column i tried this:
GridBagConstraints gbc = new GridBagConstraints();
mapPanel = new MapPanel(map);
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 10;
add(mapPanel, gbc);
controlPanel = new JPanel();
controlPanel.add(new JButton("Test"));
controlPanel.add(new JButton("Test 2"));
controlPanel.add(new JButton("Test 3"));
controlPanel.add(new JButton("Test 4"));
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridheight = 1;
add(controlPanel, gbc);
logPanel = new LogPanel();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridheight = GridBagConstraints.REMAINDER;
add(logPanel, gbc);
This however will result in everything "packed together" in the left column. It won't expand to the 100% height and 50% width the column has. How can i achieve a GUI as in the picture?
Thanks!
Look at JNodeLayout. RectNode is exactly what you Need.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import com.smartg.swing.layout.JNodeLayout;
import com.smartg.swing.layout.LayoutNode.RectNode;
public class RectNodeDemo {
public static void main(String[] args) {
String rootName = "root";
RectNode root = new RectNode(rootName);
JNodeLayout layout = new JNodeLayout(root);
layout.setHgap(1);
layout.setVgap(1);
JPanel target = new JPanel();
target.setBorder(new EmptyBorder(10, 10, 10, 10));
target.setLayout(layout);
addPanel(target, root, new Rectangle2D.Double(0, 0, .5, .5));
addPanel(target, root, new Rectangle2D.Double(0, .5, .5, .1));
addPanel(target, root, new Rectangle2D.Double(0, .6, .5, .4));
addPanel(target, root, new Rectangle2D.Double(.5, 0, .5, .9));
addPanel(target, root, new Rectangle2D.Double(.5, .9, .5, .1));
layout.syncNodes();
JFrame frame = new JFrame();
Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(target, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
static void addPanel(JPanel target, RectNode node, Rectangle2D r) {
JPanel p = new JPanel();
target.add(p);
p.setBorder(new LineBorder(Color.BLACK, 1));
node.add(p, r);
}
}
You could use the Relative Layout. This layout allows you to specify the relative sizes of each component.
To create your panel on the left the code would be something like:
RelativeLayout rl = new RelativeLayout(RelativeLayout.Y_AXIS);
rl.setFill( true );
JPanel left = new JPanel( rl );
left.add(panel1, new Float(50));
left.add(panel2, new Float(10));
left.add(panel3, new Float(40));
Using only GridBagLayout will suffice.
By setting gbc.gridheight = 10 you tell GridBag to use 10 rows for the component. (Similar to rowspan in HTML.) This, however, says nothing about the actual height of the component since rows don't have a fixed height. Consequently, this constraint doesn't have any effect when you're only using a single column. The name of the constraint is IMHO confusing.
Use GridBagConstraints.weightx and GridBagConstraints.weighty to specify where extra space should go. See How to Use GridBagLayout for more.
In combination with component's preferred sizes you'll be able to obtain a panel that will show your components when the panel is small and distribute extra space when the panel is 'too big'.
Though, as Andrew Thompson pointed out, using setPreferredSize() is not a very good way to go. Often, components already have their preferred size just fine as constructed. Just play around with all of GridBagConstraints and see what happens.
This might in the end be a better looking solution.

JPanels won't show in GridBagLayout

When I add a JPanel(1) into my GridBagLayout JPanel(2), my JPanel(1) is shrinked into a tiny square located in the middle. I don't know why this happened, because in theory it should work. I think it might have something to do with default BorderLayout? cause I read somewhere that BorderLayout puts your JPanel in the middle. But I have already set my Layout as GridBag, so I don't know why this is happening. Here's my code:
JFrame f = new JFrame("TEST");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
f.setSize(300, screenSize.height);
f.setLocation(screenSize.width - 300, 0);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagConstraints gbc = new GridBagConstraints();
JPanel panel = new JPanel(new GridBagLayout());
JPanel A = new JPanel();
Dimension d = new Dimension(270, 50);
A.setSize(d);
A.setBackground(Color.GREEN);
JPanel B = new JPanel();
B.setSize(d);
B.setBackground(Color.BLUE);
gbc.gridy = 0;
panel.add(A, gbc);
gbc.gridx = 1;
panel.add(B, gbc);
f.add(panel);
f.validate();
f.repaint();
More over, when I set the border for A and B to 100 pixels, both of them start showing up. So I am really confused!
Stop pulling your hair with GridBagLayout, try MigLayout instead, you'll save a lot of time:
http://www.miglayout.com

Swing combo boxes

Alright, so I'm simply defining a combo box like so...
JComboBox yearSelect = new JComboBox();
Now, I have not even added this to a panel or anything, I've just defined it. When I run the app, nothing displays.. when I comment out this line.. the app displays the other panels like I want it to.. is there something I'm doing wrong? Maybe I'm forgetting something that has to do with combo boxes? I think it may be something stupid that I'm missing.
Here is my entire constructor for the content.
private Container pane; // content pane
private JPanel calendarPanel; // where our calendar will go
private JPanel datePanel; // where "todays date" will go
private JPanel pnlToolbar; // tool bar for moving in the year
private JPanel bottomPanel;
private JPanel yearPanel;
private JLabel lbCurrentMonth;
private JLabel dateLabel;
private JButton monthBack;
private JButton monthForward;
private JComboBox yearSelect;
private Date today = new Date();
private int currentMonth = today.getMonth();
private int currentYear = today.getYear();
final private String [] days = {"Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday", "Friday",
"Saturday"};
final private String [] months = {"January", "Febuary", "March", "April",
"May", "June", "July", "August",
"September", "October", "November",
"December"};
public Calendar() {
// call the calendar frame class constructor (Window class)
// this function will setup our basic window
super();
// define the current date of the calendar as today
// below are attributes to our window. They define what content
// is on them.
// define our window
pane = window.getContentPane();
pane.setLayout(new BorderLayout());
calendarPanel = new JPanel(new FlowLayout());
calendarPanel.setBorder(BorderFactory.createTitledBorder("Calendar"));
pnlToolbar = new JPanel(new FlowLayout(FlowLayout.CENTER, 40, 5));
pnlToolbar.setSize(300, 45);
//////////////////////////////////////////////////////////////////////
/* setup our lower date panel, that displays todays date
and the year drop down menu */
// for "todays date"
dateLabel = new JLabel(returnDateString());
dateLabel.setFont(new Font(null, Font.BOLD, 12));
datePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5));
datePanel.add(new JLabel("Todays Date: "), BorderLayout.WEST);
datePanel.add(dateLabel, BorderLayout.EAST);
// for "year select"
// yearSelect = new JComboBox();
yearPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 5));
//yearPanel.add(yearSelect);
bottomPanel = new JPanel(new BorderLayout());
bottomPanel.add(datePanel, BorderLayout.WEST);
//bottomPanel.add(yearPanel, BorderLayout.EAST);
// setup the tool bar panel
lbCurrentMonth = new JLabel(months[currentMonth]);
monthBack = new JButton("<<");
monthForward = new JButton(">>");
monthForward.setEnabled(true);
monthBack.setEnabled(true);
pnlToolbar.add(monthBack);
pnlToolbar.add(lbCurrentMonth);
pnlToolbar.add(monthForward);
// add everything to the content panel
pane.add(calendarPanel, BorderLayout.CENTER);
pane.add(bottomPanel, BorderLayout.SOUTH);
pane.add(pnlToolbar, BorderLayout.NORTH);
You need to add a model to display your data. See JComboBox.setModel.
Yea still nothing, I've attached the rest of my code above. Even when I don't add the object to a panel, it does this. I'm simply instantiating the object, nothing more. Any ideas? Also, I've created a seperate application to make sure I'm doing the combo boxes correctly here is something I noticed. It doesnt the exact same thing in the sperate application.. below.. (very dirty)
public class Main {
public static void main(String[] args) {
String [] selectFill = {"Cat", "Dog"};
JFrame window = new JFrame("Window");
window.setBounds(0, 0 , 800, 600);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLayout(null);
//JComboBox selectBox = new JComboBox(selectFill);
JLabel check = new JLabel("Select: ");
JPanel contentPanel = new JPanel(new FlowLayout());
Container pane = window.getContentPane();
pane.add(contentPanel);
pane.setLayout(new FlowLayout());
contentPanel.add(check);
//contentPanel.add(selectBox);
}
}
For some strange reason when I resize the window, or minmize it loads the content. Or.. if I comment out the line for the combo box object it displays the content as well.