Java examples for Swing:JDialog
Dialog with list control
import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Frame; import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; /**//from w ww .j a va 2s . com * A 1.4 application that brings up a ListDialog. */ public class Main { static JFrame frame; static String[] names = { "Arlo", "Cosmo", "Elmo", "Hugo", "Jethro", "Laszlo", "Milo", "Nemo", "Otto", "Ringo", "Rocco", "Rollo" }; public static JPanel createUI() { // Create the labels. JLabel intro = new JLabel("The chosen name:"); final JLabel name = new JLabel(names[1]); intro.setLabelFor(name); // Use a wacky font if it exists. If not, this falls // back to a font we know exists. name.setFont(getAFont()); // Create the button. final JButton button = new JButton("Pick a new name..."); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String selectedName = ListDialog.showDialog(frame, button, "Baby names ending in O:", "Name Chooser", names, name.getText(), "Cosmo "); name.setText(selectedName); } }); // Create the panel we'll return and set up the layout. JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 10, 20)); intro.setAlignmentX(JComponent.CENTER_ALIGNMENT); name.setAlignmentX(JComponent.CENTER_ALIGNMENT); button.setAlignmentX(JComponent.CENTER_ALIGNMENT); // Add the labels to the content pane. panel.add(intro); panel.add(Box.createVerticalStrut(5)); // extra space panel.add(name); // Add a vertical spacer that also guarantees us a minimum width: panel.add(Box.createRigidArea(new Dimension(150, 10))); // Add the button. panel.add(button); return panel; } /** * Finds a cursive font to use, or falls back to using an italic serif font. */ protected static Font getAFont() { // initial strings of desired fonts String[] desiredFonts = { "French Script", "FrenchScript", "Script" }; String[] existingFamilyNames = null; // installed fonts String fontName = null; // font we'll use // Search for all installed font families. The first // call may take a while on some systems with hundreds of // installed fonts, so if possible execute it in idle time, // and certainly not in a place that delays painting of // the UI (for example, when bringing up a menu). // // In systems with malformed fonts, this code might cause // serious problems; use the latest JRE in this case. (You'll // see the same problems if you use Swing's HTML support or // anything else that searches for all fonts.) If this call // causes problems for you under the latest JRE, please let // us know. GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); if (ge != null) { existingFamilyNames = ge.getAvailableFontFamilyNames(); } // See if there's one we like. if ((existingFamilyNames != null) && (desiredFonts != null)) { int i = 0; while ((fontName == null) && (i < desiredFonts.length)) { // Look for a font whose name starts with desiredFonts[i]. int j = 0; while ((fontName == null) && (j < existingFamilyNames.length)) { if (existingFamilyNames[j].startsWith(desiredFonts[i])) { // We've found a match. Test whether it can display // the Latin character 'A'. (You might test for // a different character if you're using a different // language.) Font f = new Font(existingFamilyNames[j], Font.PLAIN, 1); if (f.canDisplay('A')) { fontName = existingFamilyNames[j]; System.out.println("Using font: " + fontName); } } j++; // Look at next existing font name. } i++; // Look for next desired font. } } // Return a valid Font. if (fontName != null) { return new Font(fontName, Font.PLAIN, 36); } else { return new Font("Serif", Font.ITALIC, 36); } } /** * Create the GUI and show it. For thread safety, this method should be * invoked from the event-dispatching thread. */ private static void createAndShowGUI() { // Create and set up the window. frame = new JFrame("Name That Baby"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Create and set up the content pane. JComponent newContentPane = createUI(); newContentPane.setOpaque(true); // content panes must be opaque frame.setContentPane(newContentPane); // Display the window. frame.pack(); frame.setVisible(true); } public static void main(String[] args) { // Schedule a job for the event-dispatching thread: // creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } } /* * ListDialog.java is meant to be used by programs such as ListDialogRunner. It * requires no additional files. */ /** * Use this modal dialog to let the user choose one string from a long list. See * ListDialogRunner.java for an example of using ListDialog. The basics: * * <pre> * String[] choices = { "A", "long", "array", "of", "strings" }; * String selectedName = ListDialog.showDialog(componentInControllingFrame, * locatorComponent, "A description of the list:", "Dialog Title", choices, * choices[0]); * </pre> */ class ListDialog extends JDialog implements ActionListener { private static ListDialog dialog; private static String value = ""; private JList list; /** * Set up and show the dialog. The first Component argument determines which * frame the dialog depends on; it should be a component in the dialog's * controlling frame. The second Component argument should be null if you want * the dialog to come up with its left corner in the center of the screen; * otherwise, it should be the component on top of which the dialog should * appear. */ public static String showDialog(Component frameComp, Component locationComp, String labelText, String title, String[] possibleValues, String initialValue, String longValue) { Frame frame = JOptionPane.getFrameForComponent(frameComp); dialog = new ListDialog(frame, locationComp, labelText, title, possibleValues, initialValue, longValue); dialog.setVisible(true); return value; } private void setValue(String newValue) { value = newValue; list.setSelectedValue(value, true); } private ListDialog(Frame frame, Component locationComp, String labelText, String title, Object[] data, String initialValue, String longValue) { super(frame, title, true); // Create and initialize the buttons. JButton cancelButton = new JButton("Cancel"); cancelButton.addActionListener(this); // final JButton setButton = new JButton("Set"); setButton.setActionCommand("Set"); setButton.addActionListener(this); getRootPane().setDefaultButton(setButton); // main part of the dialog list = new JList(data) { // Subclass JList to workaround bug 4832765, which can cause the // scroll pane to not let the user easily scroll up to the beginning // of the list. An alternative would be to set the unitIncrement // of the JScrollBar to a fixed value. You wouldn't get the nice // aligned scrolling, but it should work. public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { int row; if (orientation == SwingConstants.VERTICAL && direction < 0 && (row = getFirstVisibleIndex()) != -1) { Rectangle r = getCellBounds(row, row); if ((r.y == visibleRect.y) && (row != 0)) { Point loc = r.getLocation(); loc.y--; int prevIndex = locationToIndex(loc); Rectangle prevR = getCellBounds(prevIndex, prevIndex); if (prevR == null || prevR.y >= r.y) { return 0; } return prevR.height; } } return super.getScrollableUnitIncrement(visibleRect, orientation, direction); } }; list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); if (longValue != null) { list.setPrototypeCellValue(longValue); // get extra space } list.setLayoutOrientation(JList.HORIZONTAL_WRAP); list.setVisibleRowCount(-1); list.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { setButton.doClick(); // emulate button click } } }); JScrollPane listScroller = new JScrollPane(list); listScroller.setPreferredSize(new Dimension(250, 80)); listScroller.setAlignmentX(LEFT_ALIGNMENT); // Create a container so that we can add a title around // the scroll pane. Can't add a title directly to the // scroll pane because its background would be white. // Lay out the label and scroll pane from top to bottom. JPanel listPane = new JPanel(); listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS)); JLabel label = new JLabel(labelText); label.setLabelFor(list); listPane.add(label); listPane.add(Box.createRigidArea(new Dimension(0, 5))); listPane.add(listScroller); listPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // Lay out the buttons from left to right. JPanel buttonPane = new JPanel(); buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS)); buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); buttonPane.add(Box.createHorizontalGlue()); buttonPane.add(cancelButton); buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); buttonPane.add(setButton); // Put everything together, using the content pane's BorderLayout. Container contentPane = getContentPane(); contentPane.add(listPane, BorderLayout.CENTER); contentPane.add(buttonPane, BorderLayout.PAGE_END); // Initialize values. setValue(initialValue); pack(); setLocationRelativeTo(locationComp); } // Handle clicks on the Set and Cancel buttons. public void actionPerformed(ActionEvent e) { if ("Set".equals(e.getActionCommand())) { ListDialog.value = (String) (list.getSelectedValue()); } ListDialog.dialog.setVisible(false); } } /* * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Oracle or the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */