以下のコードは、FF、IE、Chrome などのブラウザで見られるマルチ ドキュメント インターフェイス (MDI) と少し似た動作をするはずです。ユーザーの選択により、ペインから新しい (または既存の) ウィンドウにドラッグできるように、タブ付きペインに「ドキュメント」 (スペーサーとしての黒いバッファリングされた画像) を表示します。
しかし、タブがなくなるとフレームを閉じたり、表示されるウィンドウがなくなったときに JVM を閉じたりするという問題がありました。の aをチェックして修正したと思います:Timer
DragTabManager
- 開いているフレームをチェックして、
DragTabFrame
- 見つかった場合は、タブ数をチェックします。0 の場合、フレームは非表示に設定され、破棄されます。
- 表示されているフレームのインスタンスが見つからない場合は
Timer
、JRE を終了できるように終了します。
少なくとも、それが機能するはずの方法です。ここでは確実に動作しているようで、かなりの数のテストで「空のフレームまたは VM がシャットダウンに失敗する」ことはありませんでした。他の人に宣伝されているように機能しますか、それともさらに調べる必要がありますか?
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class DragTabFrame extends JFrame {
private JTabbedPane tabbedPane = new JTabbedPane();
private final static DragTabManager dragTabManager = new DragTabManager();
final MouseAdapter ma = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JComponent c = (JComponent) e.getSource();
dragTabManager.setCurrentComponent(c);
DragTabFrame dtf = (DragTabFrame)c.getTopLevelAncestor();
dragTabManager.setCurrentFrame(dtf);
JTabbedPane tp = dtf.getTabbedPane();
int index = tp.indexOfComponent(c);
if (index<0) index = 0;
String title = tp.getTitleAt(index);
dragTabManager.setCurrentTitle(title);
}
@Override
public void mousePressed(MouseEvent e) {
JComponent c = (JComponent) e.getSource();
DragTabFrame dtf = (DragTabFrame)c.getTopLevelAncestor();
dragTabManager.setCurrentComponent(c);
dragTabManager.setCurrentFrame(dtf);
JTabbedPane tp = dtf.getTabbedPane();
int index = tp.indexOfComponent(c);
if (index<0) index = 0;
String title = tp.getTitleAt(index);
dragTabManager.setCurrentTitle(title);
}
@Override
public void mouseReleased(MouseEvent e) {
JComponent c = (JComponent) e.getSource();
if (c.getTopLevelAncestor().getBounds().contains(e.getLocationOnScreen())) {
// do nothing, the drop point is the same frame
} else {
DragTabFrame dtf = getTargetFrame(e.getLocationOnScreen());
if (dtf == null) {
dtf = new DragTabFrame();
dtf.init();
dtf.setLocation(e.getLocationOnScreen());
} else {
DragTabFrame fromFrame = dragTabManager.getCurrentFrame();
fromFrame.removeTabComponent(c);
JTabbedPane tp = fromFrame.getTabbedPane();
if (tp.getTabCount() == 0) {
fromFrame.setVisible(false);
fromFrame.dispose();
}
}
dtf.addTabComponent(dragTabManager.getCurrentTitle(), c);
dtf.pack();
dtf.setVisible(true);
}
}
};
public JTabbedPane getTabbedPane() {
return tabbedPane;
}
public DragTabFrame getTargetFrame(Point p) {
Frame[] frames = Frame.getFrames();
for (Frame frame : frames) {
if (frame instanceof DragTabFrame
&& frame.getBounds().contains(p)) {
return (DragTabFrame) frame;
}
}
return null;
}
public void init() {
// the GUI as seen by the user (without frame)
JPanel gui = new JPanel(new BorderLayout());
gui.setBorder(new EmptyBorder(2, 3, 2, 3));
gui.add(tabbedPane, BorderLayout.CENTER);
add(gui);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See https://stackoverflow.com/a/7143398/418556 for demo.
setLocationByPlatform(true);
}
public void addTabComponent(String name, Component c) {
tabbedPane.addTab(name, c);
c.addMouseListener(ma);
c.addMouseMotionListener(ma);
}
public void removeTabComponent(Component c) {
tabbedPane.remove(c);
c.removeMouseListener(ma);
c.removeMouseMotionListener(ma);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
DragTabFrame dtf = new DragTabFrame();
dtf.init();
BufferedImage bi = new BufferedImage(
200, 40, BufferedImage.TYPE_INT_RGB);
for (int ii = 1; ii < 4; ii++) {
JLabel l = new JLabel(new ImageIcon(bi));
dtf.addTabComponent("Tab " + ii, l);
}
dtf.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
dtf.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
class DragTabManager {
private DragTabFrame currentFrame;
private JComponent currentComponent;
private String currentTitle;
private Timer timer;
public DragTabManager() {
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Frame[] frames = Frame.getFrames();
if (frames.length==0) {
timer.stop();
}
System.out.println("frames.length: " + frames.length);
boolean allInvisible = true;
for (Frame frame : frames) {
if (frame instanceof DragTabFrame) {
DragTabFrame dtf = (DragTabFrame)frame;
if (dtf.isVisible()) {
allInvisible = false;
}
if (dtf.getTabbedPane().getTabCount()==0) {
dtf.setVisible(false);
dtf.dispose();
}
}
}
if (allInvisible) {
timer.stop();
}
}
};
timer = new Timer(200,actionListener);
timer.start();
}
/**
* @return the currentFrame
*/
public DragTabFrame getCurrentFrame() {
return currentFrame;
}
/**
* @param currentFrame the currentFrame to set
*/
public void setCurrentFrame(DragTabFrame currentFrame) {
this.currentFrame = currentFrame;
}
/**
* @return the currentComponent
*/
public JComponent getCurrentComponent() {
return currentComponent;
}
/**
* @param currentComponent the currentComponent to set
*/
public void setCurrentComponent(JComponent currentComponent) {
this.currentComponent = currentComponent;
}
/**
* @return the currentTitle
*/
public String getCurrentTitle() {
return currentTitle;
}
/**
* @param currentTitle the currentTitle to set
*/
public void setCurrentTitle(String currentTitle) {
this.currentTitle = currentTitle;
}
}
修理
DSquareの回答の提案に従って、ここに固定ソースがあり、他にもいくつかの調整があります。
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class DragTabFrame extends JFrame {
private JTabbedPane tabbedPane = new JTabbedPane();
private final static DragTabManager dragTabManager = new DragTabManager();
final MouseAdapter ma = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
JComponent c = (JComponent) e.getSource();
DragTabFrame dtf = (DragTabFrame) c.getTopLevelAncestor();
dragTabManager.setCurrentComponent(c);
dragTabManager.setCurrentFrame(dtf);
JTabbedPane tp = dtf.getTabbedPane();
int index = tp.indexOfComponent(c);
String title = tp.getTitleAt(index);
dragTabManager.setCurrentTitle(title);
}
@Override
public void mouseReleased(MouseEvent e) {
JComponent c = (JComponent) e.getSource();
if (c.getTopLevelAncestor().getBounds().contains(
e.getLocationOnScreen())) {
// do nothing, the drop point is the same frame
} else {
DragTabFrame dtf = getTargetFrame(e.getLocationOnScreen());
if (dtf == null) {
dtf = new DragTabFrame();
dtf.init();
dtf.setLocation(e.getLocationOnScreen());
}
DragTabFrame fromFrame = dragTabManager.getCurrentFrame();
fromFrame.removeTabComponent(c);
JTabbedPane tp = fromFrame.getTabbedPane();
if (tp.getTabCount() == 0) {
fromFrame.setVisible(false);
fromFrame.dispose();
}
dtf.addTabComponent(dragTabManager.getCurrentTitle(), c);
dtf.pack();
dtf.setVisible(true);
}
}
};
public JTabbedPane getTabbedPane() {
return tabbedPane;
}
public DragTabFrame getTargetFrame(Point p) {
Frame[] frames = Frame.getFrames();
for (Frame frame : frames) {
if (frame instanceof DragTabFrame
&& frame.getBounds().contains(p)) {
return (DragTabFrame) frame;
}
}
return null;
}
public void init() {
// the GUI as seen by the user (without frame)
JPanel gui = new JPanel(new BorderLayout());
gui.setBorder(new EmptyBorder(2, 3, 2, 3));
gui.add(tabbedPane, BorderLayout.CENTER);
add(gui);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See https://stackoverflow.com/a/7143398/418556 for demo.
setLocationByPlatform(true);
}
public void addTabComponent(String name, Component c) {
tabbedPane.addTab(name, c);
c.addMouseListener(ma);
c.addMouseMotionListener(ma);
}
public void removeTabComponent(Component c) {
tabbedPane.remove(c);
c.removeMouseListener(ma);
c.removeMouseMotionListener(ma);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
DragTabFrame dtf = new DragTabFrame();
dtf.init();
BufferedImage bi = new BufferedImage(
200, 40, BufferedImage.TYPE_INT_RGB);
for (int ii = 1; ii < 4; ii++) {
JLabel l = new JLabel(new ImageIcon(bi));
dtf.addTabComponent("Tab " + ii, l);
}
dtf.pack();
dtf.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
class DragTabManager {
private DragTabFrame currentFrame;
private JComponent currentComponent;
private String currentTitle;
/**
* @return the currentFrame
*/
public DragTabFrame getCurrentFrame() {
return currentFrame;
}
/**
* @param currentFrame the currentFrame to set
*/
public void setCurrentFrame(DragTabFrame currentFrame) {
this.currentFrame = currentFrame;
}
/**
* @return the currentComponent
*/
public JComponent getCurrentComponent() {
return currentComponent;
}
/**
* @param currentComponent the currentComponent to set
*/
public void setCurrentComponent(JComponent currentComponent) {
this.currentComponent = currentComponent;
}
/**
* @return the currentTitle
*/
public String getCurrentTitle() {
return currentTitle;
}
/**
* @param currentTitle the currentTitle to set
*/
public void setCurrentTitle(String currentTitle) {
this.currentTitle = currentTitle;
}
}