Say I wanted to add a JComboBox (or more general a JPanel, perhaps?) to a JRadioButton, what would be the easiest way to do it?
Pseudo-wise, a radio button group where one of them includes multiple choices would look something like:
O The weather
O Parties
O {meta, pseudo}-science
O Animals
where the {} would be a dropdown list. The trick here is that if one clicks either the dropdown list or the label '-science' the radio button would be actived and showing the UI border and all of that fancy stuff.
Thanks :)
I hate giving answers like this, but in this case I feel it is best...
This seems like a very non-standard UI component. It would be much better UX if you just did:
O The weather
O Parties
O meta-science
O pseudo-science
O Animals
Users will not be familiar with the type of component you are proposing, and it is very inconsistent with the other options in the list. I highly recommend using a more standard convention.
Against my better judgement, I present you with ComboBoxRadioButton:
It is not complete, nor do I suggest using it, but it looks like what you want.
import java.awt.FlowLayout;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JToggleButton;
public class ComboBoxRadioButton extends JRadioButton {
private JLabel beforeText, afterText;
private JComboBox comboBox;
public ComboBoxRadioButton(String beforeTxt, JComboBox comboBox,
String afterText) {
this.comboBox = comboBox;
this.beforeText = new JLabel(" " + beforeTxt);
this.afterText = new JLabel(afterText);
comboBox.setSelectedIndex(0);
setLayout(new FlowLayout());
setModel(new JToggleButton.ToggleButtonModel());
add(this.beforeText);
add(this.comboBox);
add(this.afterText);
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPane = new JPanel();
ButtonGroup group = new ButtonGroup();
AbstractButton b2 = new JRadioButton("Java Swing");
AbstractButton b3 = new ComboBoxRadioButton(
"It's gonna be a", new JComboBox(new String[] { "good", "bad",
"rainy" }), "day!");
AbstractButton b4 = new JRadioButton("After the combo");
group.add(b2);
group.add(b3);
group.add(b4);
mainPane.add(b2);
mainPane.add(b3);
mainPane.add(b4);
f.add(mainPane);
f.pack();
f.setVisible(true);
}
}
I like Justin's answer, but another alternate suggestion:
Put all the options in a single JComboBox.
If you really want to want to take the route from your question it is possible. The best way to achieve this will be to:
Create a JPanel that has a JRadioButton on the left, Combo in the middle and label to the right.
Add a mouse listener to catch clicks on the panel.
Tweak the border, layout, and possibly other UI items to make it look nice.
Related
I am attempting to add another checkbox to this program but for some reason it will not display when I run the program. Only the check box for the blue pill displays. I have attempted to add a couple things or change the way the program is structured, but nothing I have done so far has helped.
Code Below:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class CMIS242WK4DonnersonAReply {
static JCheckBox red;
static JCheckBox blue;
static JButton button;
public CMIS242WK4DonnersonAReply() {
button = new JButton("submit"); // Creates submit button
widget
ButtonHandler listener = new ButtonHandler(); // Creates the handler for the button.
button.addActionListener((ActionListener) listener); // adds the handler to the button widget
JPanel content = new JPanel(); // "container"
content.setLayout(new BorderLayout());
content.add(button, BorderLayout.PAGE_END);// places submit button at the bottom of panel.
JLabel label = new JLabel("At last. Welcome, Neo. As you no doubt have guessed, I am Morpheus. This is your last chance. After this there is no turning back."); // Label in frame.
content.add(label, BorderLayout.NORTH);// places label at the top of the screen.
//Creating Check Boxes
JCheckBox red = new JCheckBox("You take the red pill, you stay in Wonderland and I show you how deep the rabbit hole goes.");
red.setBounds(100,100, 50,50);
content.add(red);
JCheckBox blue = new JCheckBox("You take the blue pill, the story ends, you wake up in your bed and believe whatever you want to believe. ");
blue.setBounds(100,100, 50,50);
content.add(blue);
//Adding Frame
JFrame window = new JFrame("Matrix Monologue"); // JFrame = Window
window.setContentPane(content);
window.setSize(750,200); // Length, Height
window.setLocation(200,200); // X/Y "OF THE ENTIRE FRAME" Not the contents
window.setVisible(true); // makes window visible
}
// Method handles what happens when button is pressed.
private static class ButtonHandler implements ActionListener{
public void actionPerformed1(ActionEvent e) {
// Checks if which pill was selected and responds to user depending on their action.
if (red.isSelected() == true) {
System.out.println("Follow me");
System.out.println();
}
if (blue.isSelected() == true) {
System.out.println("Very Well, You may go back to your world");
System.out.println();
}
else
System.out.println("You must make a choice for what pill you will take");
System.exit(0); //closes program
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
// Main/driver method that runs everything.
public static void main(String[] args) {
CMIS242WK4DonnersonAReply matrixMonologue= new CMIS242WK4DonnersonAReply();
}
}
Any pointers?
When you're stuck on a problem, it never hurts to go back and consult the documentation.
You'll find information like this:
A border layout lays out a container, arranging and resizing its
components to fit in five regions: north, south, east, west, and
center. Each region may contain no more than one component, and is
identified by a corresponding constant: NORTH, SOUTH, EAST, WEST, and
CENTER. When adding a component to a container with a border layout,
use one of these five constants...
When you add your button, you do this:
content.add(button, BorderLayout.PAGE_END);
But then, when it's time to add checkboxes, you do this:
content.add(red);
...
content.add(blue);
Are you seeing what's missing? My bet is that you only see the blue checkbox because you added it on top of (or simply displaced) the red checkbox. Remember, the doc says "Each region may contain no more than one component..."
Try specifying the region of your BorderLayout where you want to see each checkbox.
If you want them to appear in the same region, put them in a JPanel of their own and lay them out at NORTH and SOUTH or EAST and WEST and then add that checkbox panel to your content panel in the region you want them to appear.
I feel that you need some guidance with your Swing programming. I have rewritten your CMIS242WK4DonnersonAReply class. Code is below. But first some comments about the code in your question.
JCheckBox red = new JCheckBox("You take the red pill, you stay in Wonderland and I show you how deep the rabbit hole goes.");
You have created a local variable which is hiding the class member. Hence static JCheckBox red; remains null and consequently the following if statement will throw NullPointerException.
if (red.isSelected() == true) {
By the way, the == true is not necessary. The following is sufficient.
if (red.isSelected()) {
Now another point.
red.setBounds(100,100, 50,50);
Since you are using a layout manager, namely BorderLayout, method setBounds will be ignored. The layout manager determines where to place the component on the screen.
window.setContentPane(content);
By default, the content pane of JFrame is a JPanel with BorderLayout so no need to replace the default content pane.
private static class ButtonHandler implements ActionListener
No need to create a nested class. Simply make class CMIS242WK4DonnersonAReply implement the ActionListener interface.
System.out.println("Follow me");
I don't think it's a good idea to involve the console in a GUI application. I would use JOptionPane to display a message to the user.
static JCheckBox blue;
I think that JRadioButton is more appropriate than JCheckBox in your situation.
Here is my code.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class CMIS242WK4DonnersonAReply implements Runnable, ActionListener {
private JButton button;
private JRadioButton blue;
private JRadioButton red;
private JFrame window;
#Override
public void actionPerformed(ActionEvent event) {
if (red.isSelected()) {
JOptionPane.showMessageDialog(window, "Follow me.");
}
else if (blue.isSelected()) {
JOptionPane.showMessageDialog(window, "Very Well, You may go back to your world");
}
else {
JOptionPane.showMessageDialog(window, "You must make a choice for what pill you will take");
}
}
#Override
public void run() {
createAndShowGui();
}
private void createAndShowGui() {
window = new JFrame("Matrix Monologue");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("At last. Welcome, Neo. As you no doubt have guessed, I am Morpheus. This is your last chance. After this there is no turning back."); // Label in frame.
window.add(label, BorderLayout.PAGE_START);
window.add(createCheckBoxes(), BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
button = new JButton("submit");
button.addActionListener(this);
buttonPanel.add(button);
window.add(buttonPanel, BorderLayout.PAGE_END);
window.setSize(750,200); // Length, Height
window.setLocation(200,200); // X/Y "OF THE ENTIRE FRAME" Not the contents
window.setVisible(true); // makes window visible
}
private JPanel createCheckBoxes() {
JPanel panel = new JPanel();
BoxLayout layout = new BoxLayout(panel, BoxLayout.PAGE_AXIS);
panel.setLayout(layout);
red = new JRadioButton("You take the red pill, you stay in Wonderland and I show you how deep the rabbit hole goes.");
blue = new JRadioButton("You take the blue pill, the story ends, you wake up in your bed and believe whatever you want to believe.");
ButtonGroup grp = new ButtonGroup();
grp.add(red);
grp.add(blue);
panel.add(red);
panel.add(blue);
return panel;
}
public static void main(String[] args) {
EventQueue.invokeLater(new CMIS242WK4DonnersonAReply());
}
}
Here is how the app looks when I run it.
I continue on to adding action listeners to my Java Swing buttons and fields etc. I would like to know where and when I should separate the code into classes and different methods. Unfortunately right now my code feels like it is one long script like I am used to creating in Python instead of an OOP language like Java.
How do I separate this code into classes and methods more appropriately?
Here is the code in question:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package business;
import java.awt.BorderLayout;
import java.awt.Color;
import static java.awt.Component.RIGHT_ALIGNMENT;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTree;
/**
*
* #author bob
*/
public class NewClass {
//Initialize GUI elements
JFrame myFrame = new JFrame();
JTree jtree1 = new JTree();
JTree jtree2 = new JTree();
JLabel label1 = new JLabel("Welcome to the person tester application");
JLabel label2 = new JLabel("Test2");
JLabel spacer1 = new JLabel("");
JLabel spacer2 = new JLabel("");
//buttons
JRadioButton radioCustomer = new JRadioButton("Customer");
JRadioButton radioEmployee = new JRadioButton("Employee");
ButtonGroup group = new ButtonGroup();
JButton okButton = new JButton();
JButton button2 = new JButton("Create");
JButton button3 = new JButton("EXIT");
JScrollPane sp = new JScrollPane(jtree1);
JScrollPane sp2 = new JScrollPane(jtree2);
//Panels
JPanel mainPanel = new JPanel(new GridLayout(3,1));
JPanel panel2 = new JPanel();
JPanel panel3 = new JPanel(new GridLayout(1,2));
JPanel panel4 = new JPanel();
JPanel createPanel = new JPanel();
//Constructor
public NewClass(){
}
//The createGUI method is inside the class so we can reference the GUI objects created above
public void createGUI(){
//Buttons
button2.setToolTipText("Create");
button3.setToolTipText("Exit");
button3.setForeground(Color.red);
button3.setAlignmentX(RIGHT_ALIGNMENT);
group.add(radioEmployee);
group.add(radioCustomer);
//Adding actionListeners
GUIListener myListener = new GUIListener();
okButton.addActionListener(myListener);
button2.addActionListener(myListener);
button3.addActionListener(myListener);
//adding to and customizing the panels
createPanel.setLayout(new BoxLayout(createPanel, BoxLayout.PAGE_AXIS));
createPanel.add(radioEmployee);
createPanel.add(radioCustomer);
createPanel.add(button2);
panel2.setLayout(new BoxLayout(panel2, BoxLayout.PAGE_AXIS));
panel2.add(label1);
panel2.add(createPanel);
panel3.add(BorderLayout.CENTER, sp);
panel3.add(BorderLayout.CENTER, sp2);
panel4.setLayout(new BoxLayout(panel4, BoxLayout.PAGE_AXIS));
panel4.add(spacer1);
panel4.add(button3);
//adding panels to main panel
mainPanel.add(panel2);
mainPanel.add(panel3);
mainPanel.add(panel4);
//adding panels we created to the frame
myFrame.add(mainPanel);
//setting some parameters to customize the frame
myFrame.setSize(600, 400);
myFrame.setLocationRelativeTo(null);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setVisible(true);
}
public class GUIListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == okButton){
label1.setText("okButton was pushed!");
}
else if (e.getSource() == button2){
}
else if (e.getSource() == button3){
System.out.println("button3 was pusshed");
}
}
}
//main method that makes the program run
public static void main(String[] args) {
//instantiate an object of the NewClass class
NewClass GUI = new NewClass();
//Use the method to create and display the GUI
GUI.createGUI();
}
}
This, in-of-itself, is not a easy thing to do and recognising when you should comes a lot from experience (oh, I remember last time I did this, it was horrible to manage and maintain 😝), but, there is a lot of available patterns which are used everyday to make software development easier and solve everyday common problems.
One thing you need to keep in mind is who has the responsibility to do what. For example, it might not be possible to seperate the action listeners of the buttons, as they need to perform operations which are internal to the UI itself.
However, you could make it easier through the use of Anonymous Classes or even the Actions API, which allows to isolate the functionality of the button
Another thing I would look at is isolating all the seperate containers (panels) to their own classes. This isolates the functionality and reduces the amount of complexity as it forces you to think about how each sub container is going to work and what it becomes responsible for as well as reducing unnecessary access from external influences.
A more complex solution would have the UI rely on a "model", which separated from the UI. The UI would then take actions from the user and update the model, which would intern generate notifications that the UI would use to update itself to reflect the changes, see Model-View-Controller for more details
So, what's the answer?
Break your data apart from the UI. Use one or more container/model classes to represent the data. Make use of the observer pattern to allow the model to generate events when changes occur so interested parties can take appropriate action
Break down your UI into "usable" components, where each component is isolated and responsible for managing a single portion of the UI (and how that happens is it's own business)
I would also recommend making use of dependency injection to share objects between the separated elements, this will allow you to isolate and test individual areas of your code, bonus, which also leads into...
Test Driven Development (TDD). Know what and how you want to test your code before you try and design it
I want to have a checkbox with multi-line text and I want to disable it sometimes.
Simple JCheckBox works fine and gets disabled, but it's not multiline.
Putting <html>line1<br>line2</html> provides correct size and layout, but when I disable the control, only the checkbox itself is grayed, the text remains black.
I know I can change the HTML text color to gray, but this will not work for the "Classic Windows" look-and-feel where disabled text should rendered as "sunken". Or, actually, it will work, but the appearance will differ from other disabled controls nearby, which is not good.
I can create a simple JCheckBox containing the first line of text and a JLabel with the second line and disable them simultaneously, but clicking the second line (the JLabel) doesn't activate the checkbox, and clicking the checkbox displays the keyboard focus only around the first line which confuses the user.
Is it possible to have a checkbox and its label as separate controls and have some kind of link between them, as in HTML? Probably I would be able to cook something from this.
Is it possible to subclass JButton and override something there, for example, to change the way the focus rectangle is drawn? The rectangle is drawn by com.sun.java.swing.plaf.windows.WindowsButtonUI but I'm kinda afraid of subclassing that class because it's too deep in the standard library and my application may break with a new JRE.
EDIT 04.02.2015: The above applies to Java 1.6. In Java 1.7 and higher, disabling a multi-line checkbox changes its appearance, but it still looks not the same as a disabled single-line checkbox; in particular, on Classic Windows theme the text doesn't become sunken.
(source: keep4u.ru)
I might be missing something, but I just disable the JCheckBox and the JLabel.
Using Java 1.7 and Windows Vista.
Here's the code
package com.ggl.testing;
import java.awt.BorderLayout;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class CheckBoxTest implements Runnable {
private JCheckBox checkBox;
private JLabel multiLineLabel;
private JFrame frame;
#Override
public void run() {
frame = new JFrame("Check Box Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel checkBoxPanel = new JPanel();
checkBox = new JCheckBox();
checkBoxPanel.add(checkBox);
String s = "<html>When in the course of human events it becomes"
+ "<br>necessary for one people to dissolve the political"
+ "<br>bands which have connected them with another and to"
+ "<br>assume among the powers of the earth, the separate"
+ "<br>and equal station to which the Laws of Nature and"
+ "<br>of Nature's God entitle them, a decent respect to the"
+ "<br>opinions of mankind requires that they should declare"
+ "<br>the causes which impel them to the separation.";
multiLineLabel = new JLabel(s);
multiLineLabel.setLabelFor(checkBox);
checkBoxPanel.add(multiLineLabel);
mainPanel.add(checkBoxPanel, BorderLayout.CENTER);
JPanel toggleButtonPanel = new JPanel();
JToggleButton toggleButton = new JToggleButton("Disable Checkbox");
toggleButton.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent event) {
JToggleButton toggleButton = (JToggleButton) event.getSource();
if (toggleButton.isSelected()) {
checkBox.setEnabled(false);
multiLineLabel.setEnabled(false);
} else {
checkBox.setEnabled(true);
multiLineLabel.setEnabled(true);
}
}
});
toggleButtonPanel.add(toggleButton);
mainPanel.add(toggleButtonPanel, BorderLayout.SOUTH);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new CheckBoxTest());
}
}
I'm just not understanding why things are being resized when I call the validate() and repaint() methods. I'm struggling to understand this. Essentially, my program is meant to display like this. I have a main frame into which I plug the various JPanels that I'm extending for the various functions of my photo album. The class below is the NewAlbum class that is supposed to allow the user to select files and make a new album out of them.
The code for choosing files works nicely. Once the files are selected, the change to the NewAlbum panel should be the select files button is replaced by a done button. Under the done button is a JSplitPane with the horizontal splitter just off center with the right side being larger than the left. The left side will eventually have a thumbnail of each photo as metadata about the photo is entered into the right side.
The right side pane is to be a JScrollPane with a single JPanel which has, in a grid form, the 4 entries that the user is asked for data about. After adding everything, the dimensions are where I want them to be, but when I call the validate/repaint combination the dimensions become "messed up." I'm pretty sure it's because I'm not understanding how the default layout managers for the various classes I'm using, or extending. Please help me understand. Also, tell me if the GridBagLayout is what I want, or if a different one is what I'm looking for.
The NewAlbum code is below.
I apologize for the uncompilable code. I figured that you'd be able to just look at the class and tell me, "Oh, yeah, this is the problem." Below is compilable and does demonstrate the problem. Once the files are selected, the split pane window is too thin and too long. I want it to fit inside the frame. Actually, it should fit inside the JPanel which is inside the JFrame.
Thanks,
Andy
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
class Main extends JFrame {
static JPanel transientPanel = null;
public Main() {
super();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(640, 480);
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Example");
JMenuItem albumMenu = new JMenuItem("New Album");
albumMenu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
transientPanel = new NewAlbum();
add(transientPanel);
validate();
repaint();
}
});
menu.add(albumMenu);
menuBar.add(menu);
setJMenuBar(menuBar);
validate();
}
public static void main(String[] args) {
final Main m = new Main();
m.setVisible(true);
}
}
/**
* #description NewAlbum is the window that is presented to the user
* to select new photographs for the album. Once selected, the user
* will be presented a form, of sorts, to complete the metadata for this
* album.
* #author Andy
*/
class NewAlbum extends JPanel {
JButton selectFiles;
JButton done;
JButton nextButton = new JButton("Next Image");
ArrayList<File> filesArray;
JSplitPane splitWindow = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
JScrollPane scrollWindow;
JPanel rightSidePanel = new JPanel();
JPanel leftSidePanel = new JPanel();
JLabel subjectLabel = new JLabel("Image subject:");
JLabel locationLabel = new JLabel("Image location:");
JLabel commentLabel = new JLabel("Comments:");
JLabel dateLabel = new JLabel("Date (mm/dd/yyyy):");
JTextField subjectText = new JTextField(25);
JTextField locationText = new JTextField(25);
JTextArea commentText = new JTextArea(4, 25);
JTextField dateText = new JTextField(10);
public NewAlbum() {
super();
selectFiles = new JButton("Select Photos");
selectFiles.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
selectFilesForAlbum();
}
});
add(selectFiles);
}
private void configureRightPanel() {
int jPanelX = getParent().getWidth();
int jPanelY = getParent().getHeight() - 30; // this should account for buttons
// now, resize this panel so that it will be the right size for the split pane
jPanelX = jPanelX - (int)(jPanelX * .31);
rightSidePanel.setSize(jPanelX, jPanelY);
rightSidePanel.add(subjectLabel);
rightSidePanel.add(subjectText);
rightSidePanel.add(locationLabel);
rightSidePanel.add(locationText);
rightSidePanel.add(commentLabel);
rightSidePanel.add(commentText);
rightSidePanel.add(dateLabel);
rightSidePanel.add(dateText);
rightSidePanel.add(nextButton);
// iterate over the photos selected, make bogus info for now
}
private ArrayList<File> makeFileIntoArrayList(File[] f) {
ArrayList<File> a = new ArrayList<File>();
a.addAll(Arrays.asList(f));
return filesArray = a;
}
/**
* selectFilesForAlbum
* This method is private to the NewAlbum class. It is the handler for
* when the user clicks on the "select photos" button. When the function
* executes, it displays the JFileChooser so that the user may select
* the desired photos. The files selected are assigned to a class variable
* of type File[] which is used by the enterPhotoInfo method.
*
* #return void
*/
private void selectFilesForAlbum() {
JFileChooser jfc = new JFileChooser();
jfc.setMultiSelectionEnabled(true);
jfc.showOpenDialog(this);
makeFileIntoArrayList(jfc.getSelectedFiles());
changeButtonToDone();
enterPhotoInfo();
// TODO write the photo album to the disk
}
private void changeButtonToDone() {
remove(selectFiles);
done = new JButton("Done");
add(done);
// by the time this gets called, we'll have a parent container
getParent().validate();
getParent().repaint();
}
private void enterPhotoInfo() {
splitWindow.setSize(this.getWidth(), this.getHeight() - 30);
// remove when the left side panel actually has something
Dimension iewDims = splitWindow.getSize();
int leftX = iewDims.width - (int)(iewDims.width * .69);
int leftY = iewDims.height;
leftSidePanel.setSize(leftX, leftY);
configureRightPanel();
scrollWindow = new JScrollPane(rightSidePanel);
scrollWindow.setSize(rightSidePanel.getSize());
splitWindow.setRightComponent(scrollWindow);
splitWindow.setLeftComponent(leftSidePanel);
splitWindow.setDividerLocation(.31);
System.out.println("Printing dimensions of before validate/repaint: this, splitWindow, scrollWindow, LSP, RSP");
debugPrintDimensions(this);
debugPrintDimensions(splitWindow);
debugPrintDimensions(scrollWindow);
debugPrintDimensions(leftSidePanel);
debugPrintDimensions(rightSidePanel);
//infoEntryWindow.add(infoScroller);
this.add(splitWindow);
this.validate();
this.repaint();
System.out.println("Printing dimensions of: this, splitWindow, scrollWindow, LSP, RSP");
debugPrintDimensions(this);
debugPrintDimensions(splitWindow);
debugPrintDimensions(scrollWindow);
debugPrintDimensions(leftSidePanel);
debugPrintDimensions(rightSidePanel);
}
private void debugPrintDimensions(Container c) {
System.out.println("DEBUG: Containers (x,y): (" +
String.valueOf(c.getWidth()) +
"," +
String.valueOf(c.getHeight()) +
")");
}
}
Also, tell me if the GridBagLayout is what I want, or if a different one is what I'm looking for.
You use the appropriate layout manager for the job. This can also mean using different layout managers on different panels.
splitWindow.setSize(this.getWidth(), this.getHeight() - 30);
You should NEVER use setSize(). That is the job of the layout manager, to determine the size of the component based on the rules of the layout manager.
All components have a preferred size which is used by the layout manager. At times you can use the setPreferredSize() to change the default.
By selecting a LayoutManager, you are handing over control of the layout to that layout manager. You can give the LayoutManager hints via layout constraints and restrictions by setting the preferred dimensions on the components you are arranging, but essentially, the layout manager will call the shots.
With GridBagLayoutManager you can achieve almost anything with constraints and component dimension settings, but it can still be tricky to get right. Try setting the preferred size on your components.
I used to use GridBagLayoutManager for everything, but then I came across MigLayout which really is a huge step forward in terms of easy configuration and layout consistency. I recommend you give it a look.
I'm developping a Java application.
I created this interface with MockupScreens.
Please look at these pictures.
At first time, there's only one element, the user have to enter informations (title and description) then he starts adding elements as he needs.
He can edit elemnt infomrations at any time.
He can too delete or change the order of this elements ...
How can I do to create something like the pictures up?????
Thanks in advance.
Best regards,
Ali.
I know these parts in Java Swing.
My problem is how to insert this block of buttons dynamically.
I get an idea, I must put JButtons on a JPanel then manipulate the JPanel by adding, removing and reodering...
So a Grid Layout will be efficient to add each panel after each one, but thinking on reordering the order will be so hard ...
Any suggestions please. :)
After searching, I get an idea:
Let us put these JButtons in a JPanel called btnsUnit, then manipulate it by adding, removing and reodering... So a GridLayout will be efficient to add each JPanel after each one ..
Thats why I created a new JPanel which will contain an unknown number of ListbtnsUnit JPanel, I fixed 10 as the max number.
I'm just doing these steps when you reply me. I didn't arrived to add btnsUnit JPanel in ListbtnsUnit JPanel.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
public class setupDeviceList extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
setupDeviceList frame = new setupDeviceList();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public setupDeviceList() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 742, 335);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
final JPanel ListbtnsUnit = new JPanel();
ListbtnsUnit.setBackground(Color.RED);
ListbtnsUnit.setBounds(55, 56, 243, 191);
contentPane.add(ListbtnsUnit);
ListbtnsUnit.setLayout(new GridLayout(10, 0));
final JButton btnAdd = new JButton("Add");
btnAdd.setBounds(161, 11, 56, 23);
btnAdd.setVisible(true);
btnAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
final JPanel btnsUnit = new JPanel();
btnsUnit.setBounds(343, 71, 243, 147);
contentPane.add(btnsUnit);
btnsUnit.setBackground(Color.ORANGE);
btnsUnit.setLayout(null);
btnsUnit.add(btnAdd);
ListbtnsUnit.add(btnsUnit);
ListbtnsUnit.revalidate();
ListbtnsUnit.repaint();
}
});
}
}
Please can you help me in this code.
I need just the first push to go on.
but thinking on reordering the order will be so hard ...
In your ActionListener for the button:
use getSource() method to get the button that was clicked
use the getParent() method of the button to find the panel the button belongs to
use the getParent() method of the buttons panel to find its parent panel
use the getComponents method to get an Array of all the button panels. Then loop through the Array to find the index of the panel you are search for.
once you find the index you increase of decrease the index, then you can add the panel back to its parent panel at the new index.
then you revalidate() and repaint() the parent panel to display the panel in its new location.
Nice images :-)
You need these parts, if you want to do this in Swing:
javax.swing.JButton (the several buttons)
javax.swing.JTextField (the one line text input component)
javax.swing.JTextArea (the multi-line text input component)
javax.swing.JLabel (labels for your input fields)
javax.swing.JPanel (a container to group several components together, like your lines of buttons, or the editing components at the right)
javax.swing.JFrame (the window for all together)
javax.swing.Action (actions to be performed when a button is clicked - they also can contain an icon and/or text for the button)
Look at these, start to code, and then come back if you have concrete problems. Good luck!
I think you are using a wrong idiom here. What you are trying to accomplish is usually done using JList (scrollable list of items). This way you need just one set of operations such as reorder, add and delete, next to the JList. Operations should operate on selected item in JList (otherwise they should be disabled)
Your interface may look sort of like
The idiom you're currently using is mostly done on web pages. Desktop UIs, (especially Swing) are much richer.
You can find more about how to use JList at http://download.oracle.com/javase/tutorial/uiswing/components/list.html