DragTabFrame zamyka się niekonsekwentnie
Poniższy kod powinien działać trochę jak interfejs wielu dokumentów (MDI), który możesz zobaczyć w przeglądarce, takiej jak FF, IE lub Chrome. Prezentuje „dokumenty” (czarny buforowany obraz jako spacer) w panelu z zakładkami, dzięki czemu można je przeciągać z panelu do nowego (lub istniejącego) okna według wyboru użytkownika.
Ale miał problemy z zamknięciem ramek, gdy nie mają już żadnych kart, a także zamknięcie maszyny JVM, gdy nie ma już żadnych widocznych okien. jamyśleć Naprawiłem je, sprawdzając za pomocąTimer
wDragTabManager
:
DragTabFrame
Jeśli go znajdzie, sprawdź liczbę kart. Jeśli 0 ramka jest niewidoczna i usunięta.Jeśli nie znajdzie żadnych widocznych ramek, kończyTimer
aby zezwolić JRE na wyjście.Tak przynajmniej ma działać. Wydaje się, że działa tutaj niezawodnie i nie widziałem „pustej ramki lub maszyny wirtualnej, której nie udało się zamknąć” na kilka testów. Czy działa tak, jak jest reklamowany dla innych, czy też muszę patrzeć dalej?
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;
}
}
NaprawićZgodnie z sugestiami wodpowiedź DSquare, tutaj jest stałe źródło, z kilkoma innymi poprawkami.
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;
}
}