В Windows 7 и Java 1.7 (или, если 1.6, закомментируйте две указанные строки), создайте проект NetBeans / Eclipse с именем «test» с двумя классами Test и DroppableFrame и вставьте в него этот код. А затем запустите его.
Если вы запускаете с modal = true, он мигает. Если вы запускаете с modal = false, это не так. Что я делаю не так?
// test.java
package test;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Test implements KeyListener, MouseListener
{
public Test(boolean m_modal)
{
Dimension prefSize;
Insets inset;
Font fontLabel, fontInput, fontButtons;
int buttonCenters, buttonBackoff, buttonWidth, buttonCount, thisButton, buttonTop;
String caption;
JLayeredPane m_pane;
JLabel m_lblBackground;
JScrollPane m_txtInputScroll;
int m_width, m_height, m_actual_width, m_actual_height;
boolean m_singleLineInput = true;
String m_caption = "Sample Modal Input";
m_width = 450;
m_height = m_singleLineInput ? /*single line*/180 : /*multi-line*/250;
m_frame = new DroppableFrame(false);
caption = m_caption;
m_frame.setTitle(caption);
// Compute the actual size we need for our window, so it's properly centered
m_frame.pack();
Insets fi = m_frame.getInsets();
m_actual_width = m_width + fi.left + fi.right;
m_actual_height = m_height + fi.top + fi.bottom;
m_frame.setSize(m_width + fi.left + fi.right,
m_height + fi.top + fi.bottom);
prefSize = new Dimension(m_width + fi.left + fi.right,
m_height + fi.top + fi.bottom);
m_frame.setMinimumSize(prefSize);
m_frame.setPreferredSize(prefSize);
m_frame.setMinimumSize(prefSize);
m_frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
m_frame.setSize(m_width, m_height);
m_frame.setLocationRelativeTo(null); // Center window
m_frame.setLayout(null); // We handle all redraws
Container c = m_frame.getContentPane();
c.setBackground(Color.WHITE);
c.setForeground(Color.BLACK);
m_pane = new JLayeredPane();
m_pane.setLayout(null);
m_pane.setBounds(0, 0, m_width, m_height);
m_pane.setVisible(true);
m_pane.setBorder(BorderFactory.createEmptyBorder());
c.add(m_pane);
// Set the background image
m_lblBackground = new JLabel();
m_lblBackground.setBounds(0, 0, m_width, m_height);
m_lblBackground.setHorizontalAlignment(JLabel.LEFT);
m_lblBackground.setVerticalAlignment(JLabel.TOP);
m_lblBackground.setVisible(true);
m_lblBackground.setBackground(Color.WHITE);
m_pane.add(m_lblBackground);
m_pane.moveToFront(m_lblBackground);
// Create the fonts
fontLabel = new Font("Calibri", Font.BOLD, 20);
fontInput = new Font("Calibri", Font.BOLD, 14);
fontButtons = fontLabel;
// Create the visible label contents
JLabel m_lblLabel = new JLabel();
m_lblLabel.setBounds(15, 52, 423, 28);
m_lblLabel.setHorizontalAlignment(JLabel.LEFT);
m_lblLabel.setVerticalAlignment(JLabel.CENTER);
m_lblLabel.setFont(fontLabel);
m_lblLabel.setForeground(Color.BLUE);
m_lblLabel.setText("A sample input:");
m_lblLabel.setVisible(true);
m_pane.add(m_lblLabel);
m_pane.moveToFront(m_lblLabel);
// Create the input box
if (m_singleLineInput)
{ // It's a single-line input box
m_txtInputSingleLine = new JTextField();
m_txtInputSingleLine.setBounds(15, 85, 421, 25);
m_txtInputSingleLine.setFont(fontInput);
m_txtInputSingleLine.setText("Initial Value");
m_txtInputSingleLine.setVisible(true);
m_txtInputSingleLine.addKeyListener(this);
m_pane.add(m_txtInputSingleLine);
m_pane.moveToFront(m_txtInputSingleLine);
} else {
m_txtInput = new JTextArea();
m_txtInputScroll = new JScrollPane(m_txtInput);
m_txtInputScroll.setBounds(15, 83, 421, 100);
m_txtInputScroll.setAutoscrolls(true);
m_txtInputScroll.setVisible(true);
m_txtInput.setFont(fontInput);
m_txtInput.setLineWrap(true);
m_txtInput.setWrapStyleWord(true);
m_txtInput.setTabSize(2);
m_txtInput.setText("Initial Value");
m_txtInput.setVisible(true);
m_pane.add(m_txtInputScroll);
m_pane.moveToFront(m_txtInputScroll);
}
// Determine which buttons are specified
buttonCount = 0;
m_buttons = _CANCEL_BUTTON + _OKAY_BUTTON;
if ((m_buttons & _NEXT_BUTTON) != 0)
{
m_btnNext = new JButton("Next");
m_btnNext.setFont(fontButtons);
m_btnNext.addMouseListener(this);
inset = m_btnNext.getInsets();
inset.left = 3;
inset.right = 3;
m_btnNext.setMargin(inset);
m_pane.add(m_btnNext);
m_pane.moveToFront(m_btnNext);
++buttonCount;
}
if ((m_buttons & _CANCEL_BUTTON) != 0)
{
m_btnCancel = new JButton("Cancel");
m_btnCancel.setFont(fontButtons);
m_btnCancel.addMouseListener(this);
inset = m_btnCancel.getInsets();
inset.left = 3;
inset.right = 3;
m_btnCancel.setMargin(inset);
m_pane.add(m_btnCancel);
m_pane.moveToFront(m_btnCancel);
++buttonCount;
}
if ((m_buttons & _ACCEPT_BUTTON) != 0)
{
m_btnAccept = new JButton("Accept");
m_btnAccept.setFont(fontButtons);
m_btnAccept.addMouseListener(this);
inset = m_btnAccept.getInsets();
inset.left = 3;
inset.right = 3;
m_btnAccept.setMargin(inset);
m_pane.add(m_btnAccept);
m_pane.moveToFront(m_btnAccept);
++buttonCount;
}
if ((m_buttons & _OKAY_BUTTON) != 0)
{
m_btnOkay = new JButton("Okay");
m_btnOkay.setFont(fontButtons);
m_btnOkay.addMouseListener(this);
inset = m_btnOkay.getInsets();
inset.left = 3;
inset.right = 3;
m_btnOkay.setMargin(inset);
m_pane.add(m_btnOkay);
m_pane.moveToFront(m_btnOkay);
++buttonCount;
}
// Determine the coordinates for each button
buttonCenters = (m_width / (buttonCount + 1));
buttonWidth = (int)((double)buttonCenters * 0.80);
buttonBackoff = (m_width / (buttonCount + 2)) / 2;
// Position the buttons
thisButton = 1;
buttonTop = m_singleLineInput ? 130 : 200;
if (m_btnNext != null)
{ // Position and make visible this button
m_btnNext.setBounds( + (thisButton * buttonCenters) - buttonBackoff, buttonTop, buttonWidth, 40);
m_btnNext.setVisible(true);
++thisButton;
}
if (m_btnCancel != null)
{ // Position and make visible this button
m_btnCancel.setBounds((thisButton * buttonCenters) - buttonBackoff, buttonTop, buttonWidth, 40);
m_btnCancel.setVisible(true);
++thisButton;
}
if (m_btnAccept!= null)
{ // Position and make visible this button
m_btnAccept.setBounds((thisButton * buttonCenters) - buttonBackoff, buttonTop, buttonWidth, 40);
m_btnAccept.setVisible(true);
++thisButton;
}
if (m_btnOkay != null)
{ // Position and make visible this button
m_btnOkay.setBounds((thisButton * buttonCenters) - buttonBackoff, buttonTop, buttonWidth, 40);
m_btnOkay.setVisible(true);
++thisButton;
}
// The modal code causes some slow component rendering.
// Needs looked at to figure out why
if (m_modal)
{ // Make it a modal window
m_frame.setModal(m_width, m_height, fi, m_pane);
} else {
// Make it a non-modal window
m_frame.setVisible(true);
m_frame.forceWindowToHaveFocus();
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
m_frame.dispose();
System.exit(0);
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
public static void main(String[] args)
{
boolean modal = true;
Test t = new Test(modal);
}
private DroppableFrame m_frame;
private int m_buttons;
private JTextField m_txtInputSingleLine;
private JTextArea m_txtInput;
private JButton m_btnNext;
private JButton m_btnCancel;
private JButton m_btnAccept;
private JButton m_btnOkay;
public static final int _NEXT_BUTTON = 1;
public static final int _CANCEL_BUTTON = 2;
public static final int _ACCEPT_BUTTON = 4;
public static final int _OKAY_BUTTON = 8;
public static final int _NEXT_CANCEL = 3;
public static final int _ACCEPT_CANCEL = 6;
public static final int _OKAY_CANCEL = 10;
}
// DroppableFrame.java
package test;
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.io.*;
import java.util.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.awt.event.ComponentListener;
import java.awt.event.InputEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.*;
public class DroppableFrame extends JFrame
implements DropTargetListener,
DragSourceListener,
DragGestureListener,
ComponentListener
{
public DroppableFrame(boolean isResizeable)
{
super("JFrame");
m_dragSource = DragSource.getDefaultDragSource();
m_dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
this.setDropTarget(new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this));
addComponentListener(this);
m_isResizeable = isResizeable;
m_modal = false;
setResizable(isResizeable);
}
/**
* Sets the frame to a modal state
* @param width
* @param height
*/
public void setModal(int width,
int height,
Insets fi,
JLayeredPane m_pan)
{
int i;
Component[] comps;
Component c;
Point p;
m_modal = true;
m_modalDialog = new Dialog((JFrame)null, getTitle(), true);
m_modalDialog.setLayout(null);
m_modalDialog.setResizable(m_isResizeable);
m_modalDialog.setSize(width + fi.left + fi.right, height + fi.top + (fi.bottom * 2));
m_modalDialog.setAlwaysOnTop(true);
m_modalDialog.setLocationRelativeTo(null);
if (m_pan != null)
{ // Add/copy the pane's components
comps = m_pan.getComponents();
if (comps != null)
for (i = 0; i < comps.length; i++)
{ // Add and reposition the component taking into account the insets
c = m_modalDialog.add(comps[i]);
p = c.getLocation();
c.setLocation(p.x + fi.left, p.y + fi.top + fi.bottom);
}
}
m_modalDialog.setVisible(true);
}
@Override
public void paint(Graphics g)
{
Dimension d = getSize();
Dimension m = getMaximumSize();
boolean resize = d.width > m.width || d.height > m.height;
d.width = Math.min(m.width, d.width);
d.height = Math.min(m.height, d.height);
if (resize)
{
Point p = getLocation();
setVisible(false);
setSize(d);
setLocation(p);
setVisible(true);
}
super.paint(g);
}
@Override
public void dragDropEnd(DragSourceDropEvent DragSourceDropEvent){}
@Override
public void dragEnter(DragSourceDragEvent DragSourceDragEvent){}
@Override
public void dragExit(DragSourceEvent DragSourceEvent){}
@Override
public void dragOver(DragSourceDragEvent DragSourceDragEvent){}
@Override
public void dropActionChanged(DragSourceDragEvent DragSourceDragEvent){}
@Override
public void dragEnter (DropTargetDragEvent dropTargetDragEvent)
{
dropTargetDragEvent.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
}
@Override
public void dragExit (DropTargetEvent dropTargetEvent) {}
@Override
public void dragOver (DropTargetDragEvent dropTargetDragEvent) {}
@Override
public void dropActionChanged (DropTargetDragEvent dropTargetDragEvent){}
@Override
public synchronized void drop(DropTargetDropEvent dropTargetDropEvent)
{
try
{
Transferable tr = dropTargetDropEvent.getTransferable();
if (tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
{
dropTargetDropEvent.acceptDrop (DnDConstants.ACTION_COPY_OR_MOVE);
java.util.List fileList = (java.util.List)tr.getTransferData(DataFlavor.javaFileListFlavor);
Iterator iterator = fileList.iterator();
while (iterator.hasNext())
{
File file = (File)iterator.next();
if (file.getName().toLowerCase().endsWith(".xml"))
{ // Do something with the file here
} else {
System.out.println("Ignored dropped file: " + file.getAbsolutePath());
}
}
dropTargetDropEvent.getDropTargetContext().dropComplete(true);
} else {
dropTargetDropEvent.rejectDrop();
}
} catch (IOException io) {
dropTargetDropEvent.rejectDrop();
} catch (UnsupportedFlavorException ufe) {
dropTargetDropEvent.rejectDrop();
}
}
@Override
public void dragGestureRecognized(DragGestureEvent dragGestureEvent)
{
}
public void setTranslucency(float opaquePercent)
{
try
{
if (System.getProperty("java.version").substring(0,3).compareTo("1.6") <= 0)
{ // Code for translucency works in 1.6, raises exception in 1.7
Class awtUtilitiesClass = Class.forName("com.sun.awt.AWTUtilities");
Method mSetWindowOpacity;
mSetWindowOpacity = awtUtilitiesClass.getMethod("setWindowOpacity", Window.class, float.class);
if (mSetWindowOpacity != null)
{
if (!m_modal)
mSetWindowOpacity.invoke(null, this, opaquePercent);
}
} else {
// If compiling in 1.6 or earlier, comment-out these next two lines
if (!m_modal)
setOpacity(opaquePercent);
}
} catch (NoSuchMethodException ex) {
} catch (SecurityException ex) {
} catch (ClassNotFoundException ex) {
} catch (IllegalAccessException ex) {
} catch (IllegalArgumentException ex) {
} catch (InvocationTargetException ex) {
} catch (IllegalComponentStateException ex) {
} catch (Throwable t) {
} finally {
}
}
@Override
public void componentResized(ComponentEvent e)
{
Dimension d = getSize();
Dimension m = getMaximumSize();
boolean resize = d.width > m.width || d.height > m.height;
d.width = Math.min(m.width, d.width);
d.height = Math.min(m.height, d.height);
if (resize)
setSize(d);
}
@Override
public void componentMoved(ComponentEvent e) {
}
@Override
public void componentShown(ComponentEvent e) {
}
@Override
public void componentHidden(ComponentEvent e) {
}
@Override
public void dispose()
{
if (m_modal)
{
m_modalDialog.setVisible(false);
m_modalDialog = null;
}
super.dispose();
}
public void forceWindowToHaveFocus()
{
Rectangle bounds;
Insets insets;
Robot robot = null;
if (m_modal)
m_modalDialog.setVisible(true);
setVisible(true);
toFront();
bounds = getBounds();
insets = getInsets();
try {
robot = new Robot();
robot.mouseMove(bounds.x + bounds.width / 2, bounds.y + insets.top / 2);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
} catch (AWTException ex) {
}
}
protected DragSource m_dragSource;
protected boolean m_isResizeable;
protected boolean m_modal;
protected Dialog m_modalDialog;
}