/* * This file is part of muCommander, http://www.mucommander.com * Copyright (C) 2002-2016 Maxence Bernard * * muCommander is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * muCommander is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.mucommander.ui.layout; import javax.swing.*; import javax.swing.text.JTextComponent; import java.awt.*; /** * XAlignedComponentPanel is a panel which makes life easier when having * to display several rows of label + text field. * <p>On each row, labels are right-aligned and text fields left-aligned, * looking something like this:<br> * <pre> * Label1 [Component1]<br> * LongerLabel2 [Component2]<br> * Label3 [Component3]<br> * </pre> * * <p>Vertical space between labels and components, and horizontal space between rows can both be specified. * * @author Maxence Bernard */ public class XAlignedComponentPanel extends JPanel { /** Gridbag layout constraints */ private GridBagConstraints c; /** Number of pixels between labels and components */ private int xSpace; /** * First component in this panel, which will be given the focus when focus is requested on this panel using * {@link #requestFocus()}. */ private JComponent firstComponent; public final static int DEFAULT_XPACE = 5; /** * Creates an initially empty panel, using the default vertical space as defined by {@link #DEFAULT_XPACE} to * separate labels and components for all rows added later. */ public XAlignedComponentPanel() { this(DEFAULT_XPACE); } /** * Creates an initially empty panel, using the given vertical space to separate labels and components for * all rows added later. * * @param xSpace number of pixels to be inserted between labels and components. */ public XAlignedComponentPanel(int xSpace) { // Set grid bag layout setLayout(new GridBagLayout()); setAlignmentX(LEFT_ALIGNMENT); // Number of pixels between labels and components this.xSpace = xSpace; // Init gridbag constraints. this.c = new GridBagConstraints(); this.c.anchor = GridBagConstraints.EAST; } public void setLabelLeftAligned(boolean aligned) { this.c.anchor = aligned ? GridBagConstraints.WEST : GridBagConstraints.EAST; } /** * Adds a new row with the given label and component, the component taking all the horizontal space left * by the widest label in this XAlignedComponentPanel. * * @param label text that describes the component * @param component JComponent instance, will take all remaining width space * @param ySpaceAfter number of pixels to be inserted after this row */ public void addRow(String label, JComponent component, int ySpaceAfter) { addRow(new JLabel(label), component, ySpaceAfter); } /** * Adds a new row with the given label and component, the component taking all the horizontal space left * by the widest label in this XAlignedComponentPanel. * * @param label the label component that describes the component * @param component JComponent instance that will take all remaining width space * @param ySpaceAfter number of pixels to be inserted after this row */ public void addRow(JComponent label, JComponent component, int ySpaceAfter) { if(firstComponent ==null) firstComponent = component; // Prepare grid bag constraints for label c.gridwidth = GridBagConstraints.RELATIVE; c.fill = GridBagConstraints.NONE; c.weightx = 0.0; c.insets = new Insets(0, 0, ySpaceAfter, xSpace); add(label, c); // Prepare grid bag constraints for component c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.insets = new Insets(0, 0, ySpaceAfter, 0); add(component, c); } /** * Adds a new row with the specified component left-aligned and taking all available width space. * * @param component JComponent instance that will take all available width space * @param ySpaceAfter number of pixels to be inserted after this row */ public void addRow(JComponent component, int ySpaceAfter) { // Prepare grid bag constraints c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.insets = new Insets(0, 0, ySpaceAfter, 0); add(component, c); } /** * Overrides JPanel#requestFocus() method to request focus on the first component * and select its contents if it is an instance of JTextComponent. */ @Override public void requestFocus() { if(firstComponent ==null) super.requestFocus(); else { if(firstComponent instanceof JTextComponent) { JTextComponent textComponent = (JTextComponent) firstComponent; String text = textComponent.getText(); if(!text.equals("")) { textComponent.setSelectionStart(0); textComponent.setSelectionEnd(text.length()); } } firstComponent.requestFocus(); } } }