JFrame with a list that gives information - java

I have a question regarding JFrame with a list.
I created a help menu button. Now the thing is:
When clicked a new window pops up as should. In this window I want to have a list with some formulas by name. Once a formula in the list is clicked I want to display in the same screen what the formula stands for.
It has to be something like formulas on the left in a scrollable list and in the same screen on the right in some sort of text box the description of the clicked formula.
Does anyone know how to do this?
menuItem = new JMenuItem("Help");
menuItem.setMnemonic(KeyEvent.VK_H);
menuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JFrame help = new JFrame("HELP");
help.setTitle("Help");
help.setSize(400,200);
help.setLocationRelativeTo(null);
help.setDefaultCloseOperation(help.DISPOSE_ON_CLOSE);
help.setVisible(true);
help.add(label);
String labels[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "x", "y"};
JList list = new JList(labels);
JScrollPane scrollPane = new JScrollPane (list);
Container contentPane = help.getContentPane();
contentPane.add(scrollPane, BorderLayout.CENTER);
}
});

Suggestions:
The help menu that pops up should be a dialog of some sort, perhaps a non-modal JDialog.
You should have it use a CardLayout so that it initially shows formula names, perhaps in a JList held by a JScrollPane.
When a JList item is selected, swap views via the CardLayout and display the appropriate formula.
Links:
CardLayout Tutorial
JList Tutorial
Edit
You state in comment,
It has to be something like i have my formulas on the left with a scrollbar, and in the right side of the screen some sort of textbox with the description of the formula.
Shouldn't this any any other pertinent information and restrictions be part of your original question? If I were you, I'd edit the original post and supply all necessary information so that we can fully understand your problem including pertinent code (best as an sscce). So...
Use another layout manager such as a GridLayout or better yet a BorderLayout to allow you to show multiple JPanels in another JPanel. I'll leave it to you to find the links to the Swing layout manager tutorials.
You can still use a CardLayout to swap the equations shown on the display JPanel.
Edit 2
Regarding your latest code post:
Again, the dialog window should be a JDialog not a JFrame. The window is dependent on the window that is displaying it and so should not be an independent application window such as a JFrame.
I'd place the JScrollPane in the BorderLayout.LINE_START position and the CardLayout using equation JPanel in the BorderLayout.CENTER position.
You don't have to use a CardLayout. If the equations are nothing but basic text, you can simply change the text of a JLabel.
Or if images, then swap the ImageIcon of a JLabel.
Or if a lot of text, then text in a non-editable, non-focusable JTextArea
Edit 3
is there a way to set the size to a fixed size of the scrollpane BorderLayout.LINE_START?
Rather than trying to set the size of anything, consider calling some methods on your JList, methods such as, setPrototypeCellValue(E prototypeCellValue) and setVisibleRowCount(int visibleRowCount) which will allow the component to set its own preferredSize based on reasonable data and initial assumptions. Please check the JList API for the details on these and other JList methods.

Here comes a basic implementation.
How the second (formula) window may look like:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Window;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class FormulaWindow extends JDialog {
public FormulaWindow(final Window parent) {
super(parent, "Formula window", ModalityType.MODELESS);
final Container cp = getContentPane();
cp.setLayout(new BorderLayout());
setSize(500, 400);
final Map<String, String> formulaDescritions = new HashMap<>();
formulaDescritions.put("Formula 1", "<html>How the world works.</html>");
formulaDescritions.put("Formula 2", "<html>How woman work.</html>");
formulaDescritions.put("Formula 3", "<html>How programming works.</html>");
final JList<String> formulaList = new JList<String>(new Vector<String>(formulaDescritions.keySet()));
formulaList.setPreferredSize(new Dimension(100, 100));
final JLabel descriptionLabel = new JLabel();
descriptionLabel.setVerticalAlignment(SwingConstants.TOP);
formulaList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
final JList<String> list = (JList<String>) evt.getSource();
descriptionLabel.setText(formulaDescritions.get(list.getSelectedValue()));
}
});
cp.add(new JScrollPane(formulaList), BorderLayout.WEST);
cp.add(new JScrollPane(descriptionLabel), BorderLayout.CENTER);
}
}
How to open it on selection of a menu item in the main window:
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
public class MainWindow extends JFrame {
private class ShowFormulaWindowAction extends AbstractAction {
public ShowFormulaWindowAction() {
super("Show formulas...");
}
public void actionPerformed(ActionEvent actionEvent) {
FormulaWindow formulaWindow = new FormulaWindow(MainWindow.this);
formulaWindow.setVisible(true);
}
}
public MainWindow() {
super("Main window");
JMenu fileMenu = new JMenu("Extras");
fileMenu.add(new JMenuItem(new ShowFormulaWindowAction()));
JMenuBar menuBar = new JMenuBar();
menuBar.add(fileMenu);
setJMenuBar(menuBar);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public static void main(final String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MainWindow mainWindow = new MainWindow();
mainWindow.setSize(350, 250);
mainWindow.setVisible(true);
}
});
}
}
Further notes:
The secondary window should not be a JFrame but rather a JDialog. In that way
it does not show another icon on the task bar
it can be "owned" by the main window, causing the dialog to be closed automatically, when the owner is closed

Related

My JCheckBox program only displays one box. Why is that?

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.

how to display table when the menu bar is is clicked?

may I know how to display out the table when the menu bar is clicked?
Below is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
public class Exercise03 extends JFrame {
public Exercise03() {
String[] columns = {
"No", "DO NUMBERS", "INVOICE NUMBERS", "OUTLET", "SUBMITTED BY", "CHECKED BY"
};
Object [][] input = new Object[][] {
{"1", "NKK/DO200100001", "NKK/IV200100001", "K", "A", "B"}
};
JMenuBar menuBar;
JMenu menu;
JMenuItem menuItem1;
menuBar = new JMenuBar();
menu = new JMenu ("Menu");
menu.setMnemonic(KeyEvent.VK_A);
menuBar.add(menu);
menuItem1 = new JMenuItem("Invoice", KeyEvent.VK_I);
menu.add(menuItem1);
menuItem1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
JTable menuItem1 = new JTable(input, columns);
JScrollPane pane = new JScrollPane(menuItem1);
pane.add(menuItem1);
pane.setVisible(true);
}
});
setJMenuBar(menuBar);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Documentation Checklist");
setSize(300,100);
setVisible(true);
}
public static void main (String[]args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Exercise03();
}
});
}
}
Right now I am able to display out the "menu" bar and when I clicked it, it shows one submenus which is "Invoice" but when I clicked the submenu "Invoice", it does not shows out the table below the menu bar.
My expected output is when I click the submenu "Invoice", it will shows up a table below the menu bar.
So may I know how to code to display such result ?
First of all you need to learn how to use a JScrollPane:
JScrollPane pane = new JScrollPane(menuItem1);
//pane.add(menuItem1);
Only the first statement is needed. The scroll pane has a "viewport" to display the component. So the table needs to be added to the viewport, which is done automatically when you create the scroll pane with the table as the parameter in the constructor.
Read the section from the Swing tutorial on How to Use Scroll Panes for more details on how the scroll pane works.
Then to dynamically add the scroll pane to the frame:
Don't change the layout to a FlowLayout. The default BorderLayout will be a better layout manager for the frame. It will allow components to resize dynamically as the frame is resized.
You create a JScrollPane, but you never add it to the frame. So you need to add the scroll pane to the frame. The setVisible() statement is not needed since all Swing components are visible by default
Once you add the scroll pane to the frame you need to invoke revalidate() on the panel you add the scroll pane to. In this case since you add it to the content pane you can just invoke revalidate() on the frame. The revalidate() will invoke the layout manager to give the scroll pane a size and location.
The other solution is to create the JScrollPane in the constructor of your class and add it to the frame. You would then need to save the scroll pane as an instance variable of your class. Then when you click on the menu item you can create the JTable and add the table to the scroll pane using:
scrollPane.setViewportView( menuItem1 );
then you don't need to worry about the revalidate().

Swing JDialog width too wide

I am trying to make a modeless dialog menu in Swing that is displayed upon the press of a button. The dialog contains several menu items. My problem is that the dialog window is much wider than necessary. I am looking for help on setting the window width.
Here's what the output looks like. Notice that the window containing the menu items is much wider than the items themselves. That's what I want to fix.
Here's minimal code that shows this problem:
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test().run();
}
TestDialog testDialog;
private void run() {
JFrame jframe = new JFrame();
JButton jbutton = new JButton("test");
jframe.add(jbutton);
jbutton.setBounds(130, 100, 100, 40);
jframe.setSize(400, 500);
jframe.setLayout(null);
jframe.setVisible(true);
testDialog = new TestDialog(SwingUtilities.windowForComponent(jframe));
jbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
testDialog.show();
}
});
}
private class TestDialog {
JDialog jdialog;
public TestDialog(Window parent) {
jdialog = new JDialog(parent, "Test", Dialog.ModalityType.MODELESS);
jdialog.setPreferredSize(new Dimension(100, 0));
jdialog.setLayout(new BoxLayout(jdialog.getContentPane(), BoxLayout.Y_AXIS));
JMenuItem jmenuItem1 = new JMenuItem("MenuItem 1");
Dimension jmiDimension = jmenuItem1.getPreferredSize();
System.out.printf("jmenuItem1 is %f x %f%n", jmiDimension.getWidth(), jmiDimension.getHeight());
jdialog.add(jmenuItem1);
jdialog.add(new JMenuItem("MenuItem 2"));
jdialog.pack();
Dimension d = jdialog.getSize();
System.out.printf("jdialog is %f x %f%n", d.getWidth(), d.getHeight());
}
public void show() {
jdialog.setVisible(true);
}
}
}
The program prints this output, showing that the dialog is 324 pixels wide but the menu items are 87:
jmenuItem1 is 87.000000 x 21.000000
jdialog is 324.000000 x 88.000000
I have also tried using the jdialog.setSize() and jdialog.setMaximumSize() methods. And I've tried setting the maximum size of the menu items. None of them seem to have any affect upon the dialog's window size.
I also tried a GridLayout, rather than a BoxLayout - that also made no difference.
I also tried setting the width of the dialog's content pane and layered pane. Still no difference.
I noted that the dialog has no owner nor parent.
testDialog = new TestDialog(SwingUtilities.windowForComponent(jframe));
You don't need to use the windowForComponent(...) method. You already have a reference to the parent frame:
testDialog = new TestDialog( jframe );
Don't attempt to hard code sizes. Each component will determine its own preferred size and the then layout manager will use this information to determine the overall size.
//jdialog.setPreferredSize(new Dimension(100, 0));
A JMenuItem was designed to be used on a JMenu. Instead you should be using a JButton to add to a regular panel.
I don't have a problem with the size. The width/height of the dialog is as expected.
Note I use JDK 11 on Windows 10. When I ran your original code, the dialog had no size since the setPreferredSize() statement caused the height to be 0. So I'm not sure how you get the display shown in your image.
And yes the dialog width is wider than the component added to the frame because there is a minimum width to the dialog to be able to be able to display the title bar even if no components are added to the dialog.

Understanding layout managers -- I'm not, please enlighten me

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.

JComboBox within a JRadioButton

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.

Categories

Resources