---
category: swing
folder: ColumnRules
title: JSeparatorで段落罫線を描画する
tags: [JSeparator, JLayer, Border, GridLayout, GridBagLayout]
author: aterai
pubdate: 2021-08-16T01:18:16+09:00
description: GridLayoutなどで作成した列の間に罫線としてJSeparatorを描画します。
image: https://drive.google.com/uc?id=1n9PtghYLYyFH2fXRweyIthvJhNYfa2Mz
---
* Summary [#summary]
`GridLayout`などで作成した列の間に罫線として`JSeparator`を描画します。
#download(https://drive.google.com/uc?id=1n9PtghYLYyFH2fXRweyIthvJhNYfa2Mz)
* Source Code Examples [#sourcecode]
#code(link){{
JPanel p1 = new JPanel(new GridBagLayout());
p1.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.CENTER;
c.gridheight = 1;
c.gridwidth = 1;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1.0;
c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
p1.add(new JLabel("left", SwingConstants.CENTER), c);
c.gridx = 1;
c.weightx = 0.0;
c.fill = GridBagConstraints.VERTICAL;
p1.add(new JSeparator(SwingConstants.VERTICAL), c);
c.gridx = 2;
c.weightx = 1.0;
c.fill = GridBagConstraints.BOTH;
p1.add(new JLabel("right", SwingConstants.CENTER), c);
JPanel p2 = new JPanel(new GridLayout(0, 2, 5, 5));
p2.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5), new ColumnRulesBorder()));
JPanel p3 = new JPanel(new GridLayout(0, 2, 5, 5));
p3.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
Stream.of(p2, p3).forEach(p -> {
p.add(new JLabel("left", SwingConstants.CENTER));
p.add(new JLabel("right", SwingConstants.CENTER));
});
}}
* Description [#explanation]
* Description [#description]
- `GridBagLayout`
-- `JPanel`に`3`列の`GridBagLayout`を設定
-- 中央の余分の水平スペースを分配を`0`に設定して縦`JSeparator`を追加
--- `JSeparator`がすこし左にずれる?
-- [[Componentの3列配置、中央幅固定、左右均等引き伸ばしを行うLayoutManagerを作成する>Swing/ThreeColumnLayout]]
- `GridLayout + Border`
-- `JPanel`に`2`列の`GridLayout`を設定
-- コンポーネントの中央に`SwingUtilities.paintComponent(...)`メソッドを使用して`JSeparator`のコピーを描画する`Border`を作成
-- `CompoundBorder`で元の`Border`と組み合わせて`JPanel`に設定して段落罫線を描画
-- [[JMenuから開くポップアップウィンドウのレイアウトを2列に変更する>Swing/TwoColumnsMenu]]
#code{{
class ColumnRulesBorder implements Border {
private final Insets insets = new Insets(0, 0, 0, 0);
private final JSeparator separator = new JSeparator(SwingConstants.VERTICAL);
private final Container renderer = new JPanel();
@Override public void paintBorder(
Component c, Graphics g, int x, int y, int width, int height) {
if (c instanceof JComponent) {
Rectangle r = SwingUtilities.calculateInnerArea((JComponent) c, null);
int sw = separator.getPreferredSize().width;
int sh = r.height;
int sx = (int) (r.getCenterX() - sw / 2d);
int sy = (int) r.getMinY();
Graphics2D g2 = (Graphics2D) g.create();
SwingUtilities.paintComponent(g2, separator, renderer, sx, sy, sw, sh);
g2.dispose();
}
}
@Override public Insets getBorderInsets(Component c) {
return insets;
}
@Override public boolean isBorderOpaque() {
return true;
}
}
}}
- `GridLayout + JLayer`
-- `JPanel`に`2`列の`GridLayout`を設定
-- コンポーネントの中央に`SwingUtilities.paintComponent(...)`メソッドを使用して`JSeparator`のコピーを描画する`LayerUI`を作成
-- `JLayer`で`JPanel`をラップして段落罫線を描画
-- [[JSplitPaneのDividerを円形半透明のつまみに変更して中央に配置する>Swing/TranslucentThumbDivider]]
#code{{
class ColumnRulesLayerUI extends LayerUI<JComponent> {
private final JSeparator separator = new JSeparator(SwingConstants.VERTICAL);
private final Container renderer = new JPanel();
@Override public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (c instanceof JLayer) {
JComponent tc = (JComponent) ((JLayer<?>) c).getView();
Rectangle r = SwingUtilities.calculateInnerArea(tc, null);
int sw = separator.getPreferredSize().width;
int sh = r.height;
int sx = (int) (r.getCenterX() - sw / 2d);
int sy = (int) r.getMinY();
Graphics2D g2 = (Graphics2D) g.create();
SwingUtilities.paintComponent(g2, separator, renderer, sx, sy, sw, sh);
g2.dispose();
}
}
}
}}
* Reference [#reference]
- [[Componentの3列配置、中央幅固定、左右均等引き伸ばしを行うLayoutManagerを作成する>Swing/ThreeColumnLayout]]
- [[JMenuから開くポップアップウィンドウのレイアウトを2列に変更する>Swing/TwoColumnsMenu]]
- [[JSplitPaneのDividerを円形半透明のつまみに変更して中央に配置する>Swing/TranslucentThumbDivider]]
* Comment [#comment]
#comment
#comment