Наличие левой и правой выровненной метки внутри JCheckBox
Сначала я начну с того, что хочу, и оттуда:
+------------------------------------------+
|[] jCheckBox jLabel |
+------------------------------------------+
В принципе, я хотел бы иметь JCheckBox
с двумя сегментами текста, 1 выровненными по левому краю и 1 выровненными по правому краю. Я хотел бы, чтобы весь ящик был доступен для кликабельности и действовал точно так же, как JCheckBox
(Так как, если я нажимаю на мышь, он выделяет поле ect.).
Теперь я пробовал:
-
Использование HTML внутри текстового поля со следующей таблицей: <html><table width=100%><tr width=100%><td>Left Text</td><td align=right>Right Text</td></tr></table>
. Это создает [] Left TextRightText
без какого-либо визуального выравнивания.
-
Добавление как панели JCheckBox
, так и JLabel
, однако это потребует от меня реализовать все события мыши и вызвать соответствующие соответствующие методы в JCheckBox
. Я отложил это в сторону - однако я готов пересмотреть, если это единственный вариант
-
Добавление JLabel в JCheckBox
- Во-первых, это заставило JCheckBox принять решение об изменении шрифта, поэтому его нужно было "скорректировать"
- Во-вторых, базовые линии отключены на 1 или 2 пикселя. Это было исправлено путем реализации LayoutManager, который поместил
JLabel
в базовую линию.
- В-третьих,
JLabel
перекрывается с текстом JCheckBox
, поэтому я должен настроить мой менеджер макета, однако JCheckBox
не дал правильный результат из getPreferedSize()
(из [1,1]
).
Итак, в основном мой вопрос: как мне это реализовать?
Ответы
Ответ 1
-
создать родительский JLabel
, JLabel
не реализовал ни одного LayoutManager
, а затем установить правильный LayoutManager
, я думаю, что GridLayout (with 2 segments of text, 1 left aligned and 1 right aligned
)
-
добавьте два JLabels
с правильным выравниванием (JLabel.setHorizontalAlignment(javax.swing.SwingConstants.XXX);
)
-
собрать JCheckBox
с родительским JLabel
(JLabel.setLabelFor(JCheckBox);
)
-
аналогично для MultiIcon в JLabel
Ответ 2
Вот как мне удалось реализовать его, используя JCheckBox в качестве родительского класса. Отсутствуют методы установки текста и цвета меток.
package mock.dlect;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.LayoutManager;
import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
public class LeftRightCheck extends JCheckBox {
private final static JCheckBox DEFAULT_CHECK_BOX = new JCheckBox();
private final JLabel rightLabel;
public LeftRightCheck(String leftText, String rightText, Icon icon,
boolean selected) {
super(leftText, icon, selected);
rightLabel = new JLabel(rightText, TRAILING);
// TODO figure out how to make the font work right on OSX
this.setLayout(new BaseLineSingleElementLayoutManager(10));
this.add(rightLabel);
}
@Override
public final void setFont(Font font) {
font = font.deriveFont(DEFAULT_CHECK_BOX.getFont().getSize2D());
super.setFont(font);
if (rightLabel != null) {
rightLabel.setFont(font);
}
}
private class BaseLineSingleElementLayoutManager implements LayoutManager {
private int hgap;
private Component component;
public BaseLineSingleElementLayoutManager(int hgap) {
this.hgap = hgap;
}
@Override
public void addLayoutComponent(String name, Component comp) {
// Do Nothing
}
@Override
public void removeLayoutComponent(Component comp) {
// Do Nothing
}
@Override
public Dimension preferredLayoutSize(Container parent) {
if (parent != null && parent instanceof JCheckBox) {
JCheckBox cc = (JCheckBox) parent;
// These 2 lines will add the size of the checkbox to the
// preferred size
Dimension parentSize = DEFAULT_CHECK_BOX.getPreferredSize();
parentSize.width += cc.getFontMetrics(cc.getFont()).
stringWidth(cc.getText()) + hgap;
if (checkComponent(cc)) {
Dimension childSize = this.component.getPreferredSize();
parentSize.height = Math.max(parentSize.height,
childSize.height);
parentSize.width += childSize.width;
}
return parentSize;
}
return new Dimension();
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return preferredLayoutSize(parent);
}
@Override
public void layoutContainer(Container parent) {
if (!checkComponent(parent)) {
return;
}
this.component.setSize(parent.getSize());
this.component.setLocation(0, getBaseline(parent)
- getBaseline(this.component));
}
private int getBaseline(Component c) {
return c.getBaseline(c.getWidth(), c.getHeight());
}
protected boolean checkComponent(Container parent) {
if (parent == null) {
return false;
} else if (parent.getComponentCount() >= 1
&& parent.getComponent(0).isVisible()) {
this.component = parent.getComponent(0);
return true;
} else {
return false;
}
}
}
}
Ответ 3
public class LeesCheckbox extends JPanel
{
private JCheckBox checkbox;
public LeesCheckbox(String leftText, String rightText){
super(new BorderLayout());
checkbox = new JCheckBox(leftText);
add(checkbox, BorderLayout.WEST);
add(new JLabel(rightText), BorderLayout.EAST);
setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
checkbox.setSelected(!checkbox.isSelected());
}
});
}
public JCheckBox getCheckbox() {
return checkbox;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Box content = new Box(BoxLayout.Y_AXIS);
content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
LeesCheckbox box = new LeesCheckbox("Left text", "Right text");
box.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
content.add(box);
content.add(Box.createVerticalGlue());
frame.setContentPane(content);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}