CrossSplitPane
十字分割窓のひな形を作ってみました。
もうチョット丁寧に作らないとダメですが、基本的な動作はできてます。
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; public class CrossSplitPaneTest extends JPanel { public static final int DIVIDER_WIDTH = 5; // 幅[dot] protected JComponent pane = new JComponent[2][2]; // 常に2x2 protected int splitX; // 分割バーの左の座標 protected int splitY; // 分割バーの上の座標 public CrossSplitPaneTest() { setLayout(new JSpreadLayoutManager()); splitX = 100; splitY = 100; CrossSplitListener mouselistener = new CrossSplitListener(); addMouseListener(mouselistener); addMouseMotionListener(mouselistener); } public void paintComponent(Graphics g) { super.paintComponent(g); Rectangle rect = getBounds(); g.setColor(Color.BLUE); g.fillRect(0, 0, rect.width, rect.height); } public void setPane(int row, int col, JComponent comp) { if (pane[row][col] != null) remove(pane[row][col]); pane[row][col] = comp; add(comp); } public class JSpreadLayoutManager implements LayoutManager { JSpreadLayoutManager() { } /** 指定されたコンテナを配置します。 */ public void layoutContainer(Container target) { synchronized (target.getTreeLock()) { // 一応インセットも対応しているのでボーダーが正しく使える。 Insets insets = target.getInsets(); int x0 = insets.left; int y0 = insets.top; int x9 = target.getWidth() - insets.right; int y9 = target.getHeight() - insets.bottom; int x1 = splitX; int y1 = splitY; int x2 = x1 + DIVIDER_WIDTH; int y2 = y1 + DIVIDER_WIDTH; pane[0][0].setBounds(x0, y0, x1-x0, y1-y0); pane[0][1].setBounds(x2, y0, x9-x2, y1-y0); pane[1][0].setBounds(x0, y2, x1-x0, y9-y2); pane[1][1].setBounds(x2, y2, x9-x2, y9-y2); } } public Dimension minimumLayoutSize(Container parent) { return new Dimension(0,0); // 本当は個々のペインの最小サイズを加算すべき } public Dimension preferredLayoutSize(Container parent) { return new Dimension(200, 200); // 本当は個々のペインの推奨サイズを加算すべき } public void addLayoutComponent(String name, Component comp){} public void removeLayoutComponent(Component comp) {} } /** * マウスで分割位置を変えるリスナ. * 本当は中心以外は、縦横どちらかの移動にした方がいい。 */ class CrossSplitListener extends MouseInputAdapter { int last_x = 0; int last_y = 0; public void mousePressed(MouseEvent e) { System.out.println(e); last_x = e.getX(); last_y = e.getY(); } public void mouseReleased(MouseEvent e) { System.out.println("splitX="+splitX+" e.getX()="+e.getX()+" getX()="+getX()); splitX = e.getX(); // 本当はもっと座標の範囲チェックなどをした方がよい splitY = e.getY(); revalidate(); } public void mouseDragged(MouseEvent e) { System.out.println(e); Graphics g = getParent().getGraphics(); g.setXORMode(Color.WHITE); g.fillRect(last_x, 0, DIVIDER_WIDTH, getHeight()); // hide g.fillRect(0, last_y, getWidth(), DIVIDER_WIDTH); // hide last_x = e.getX(); last_y = e.getY(); g.fillRect(last_x, 0, DIVIDER_WIDTH, getHeight()); // show g.fillRect(0, last_y, getWidth(), DIVIDER_WIDTH); // show } public void mouseMoved(MouseEvent e) { setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); } public void mouseClicked(MouseEvent e) { // 左ボタンでダブルクリックしたとき、分割を解除する。・・・とか } } public static void main(String[] args) { JFrame frame = new JFrame(); CrossSplitPaneTest divider = new CrossSplitPaneTest(); divider.setPane(0, 0, new JTextArea("(0,0)のペインだよ")); divider.setPane(0, 1, new JTextArea("(0,1)のペインだよ")); divider.setPane(1, 0, new JTextArea("(1,0)のペインだよ")); divider.setPane(1, 1, new JTextArea("(1,1)のペインだよ")); //divider.setBorder(new TitledBorder("ぼーだー")); frame.getContentPane().add(divider); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(640, 480); frame.setVisible(true); } }