怎样用JInternalFrame做出模态的效果 模态对话框很好做,可是非常不好看.特别是和我的整个软件的风格不一致,所以我想用JInternalFrame达到模态的效果.我初步想的是让其拒绝失去焦点这个属性请求.可好像不行. 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 首先,只提供了InternalFrame下用的简单的Dialog,不是和JDialog那样任意的Dialog.再则,那样的外观也不符合我的要求. 那就有些麻烦了,我又些相关的原码,没有具体再试,你参考一下巴。package accessible;import javax.accessibility.*;import javax.swing.*;import java.awt.*;class CustomInternalFrame extends JInternalFrame { public boolean isModel = false; public CustomInternalFrame(String str,boolean a,boolean b,boolean c,boolean d){ super(str,a,b,c,d); } public synchronized void startModal() { System.out.println("startModa"); if(isVisible() && !isShowing()) { System.out.println("isSho"); for(Container container = super.getParent(); container != null; container = container.getParent()) if(!container.isVisible()) container.setVisible(true); } try { if(SwingUtilities.isEventDispatchThread()) { System.out.print("isEventDispatchThread"); EventQueue eventqueue = getToolkit().getSystemEventQueue(); while(isVisible()) { AWTEvent awtevent = eventqueue.getNextEvent(); Object obj = awtevent.getSource(); if(awtevent instanceof ActiveEvent) ((ActiveEvent)awtevent).dispatch(); else if(obj instanceof Component) ((Component)obj).dispatchEvent(awtevent); else if(obj instanceof MenuComponent) ((MenuComponent)obj).dispatchEvent(awtevent); else System.err.println("unable to dispatch event: " + awtevent); } } else { System.out.print("wait"); for(; isVisible(); wait()); } } catch(InterruptedException interruptedexception) { } isModel = true; } public synchronized void stopModal() { super.notifyAll(); isModel = true; }} public static Object showInternalInputDialog(Component component, Object obj, String s, int i, Icon icon1, Object aobj[], Object obj1) { JOptionPane joptionpane = new JOptionPane(obj, i, 2, icon1, null, null); joptionpane.setWantsInput(true); joptionpane.setSelectionValues(aobj); joptionpane.setInitialSelectionValue(obj1); JInternalFrame jinternalframe = joptionpane.createInternalFrame(component, s); joptionpane.selectInitialValue(); jinternalframe.setVisible(true); jinternalframe.startModal(); Object obj2 = joptionpane.getInputValue(); if(obj2 == UNINITIALIZED_VALUE) return null; else return (String)obj2; } public JInternalFrame createInternalFrame(Component component, String s) { Object obj = getDesktopPaneForComponent(component); if(obj == null && (component == null || (obj = component.getParent()) == null)) throw new RuntimeException("JOptionPane: parentComponent does not have a valid parent"); final JInternalFrame iFrame = new JInternalFrame(s, false, false, false, false); iFrame.putClientProperty("JInternalFrame.frameType", "optionDialog"); addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent propertychangeevent) { if(iFrame.isVisible() && propertychangeevent.getSource() == JOptionPane.this && (propertychangeevent.getPropertyName().equals("value") || propertychangeevent.getPropertyName().equals("inputValue"))) { try { iFrame.setClosed(true); } catch(PropertyVetoException propertyvetoexception1) { } iFrame.setVisible(false); iFrame.stopModal(); } } }); iFrame.getContentPane().add(this, "Center"); if(obj instanceof JDesktopPane) ((Container) (obj)).add(iFrame, JLayeredPane.MODAL_LAYER); else ((Container) (obj)).add(iFrame, "Center"); Dimension dimension = iFrame.getPreferredSize(); Dimension dimension1 = ((Component) (obj)).getSize(); iFrame.setBounds((dimension1.width - dimension.width) / 2, (dimension1.height - dimension.height) / 2, dimension.width, dimension.height); ((Container) (obj)).validate(); try { iFrame.setSelected(true); } catch(PropertyVetoException propertyvetoexception) { } return iFrame; } 大哥...能不能把和这些原码一起的其他码或则别的什么发过来看看.[email protected] 到javaworld上去搜索:model或internalframe 其实JInternalFrame已经实现了模态,在JOptionPane.showInternalInputDialog()的原码中已经利用了这点,所以出来的Dialog其实也是一个JInternalFrame,但是JInternalFrame中的startModal()和stopModal()是受保护的,只能本包内的用,所以外面不能用。你可以直接另写一个类把这两个方法改为公用的,然后参考JOption的方法来用它。原码我已经反编了,给你发过去。 OK.搞定了.我开始以为是这样的.但结果发现如果上面放了个JComboBox,JComboBox不能正常工作.原因应该是这个InternalFrame是Toppest,而点击ComboBox时弹出了一个新的窗口...这样,就选不到这个新弹出的窗口了(ComboBox弹出的).原代码:文件1------------------Modal.java///////Modal.java/////////////////////package modalframe;import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;import java.beans.*;public class Modal{public static void main(String args[]){ final JFrame frame = new JFrame("Main"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final JDesktopPane desktop = new JDesktopPane(); ActionListener showModal = new ActionListener() { public void actionPerformed(ActionEvent e) { // Construct a message internal frame popup JInternalFrame iFrame = new ModalFrame("Really Modal",frame.getRootPane(), desktop); iFrame.setVisible(true); } }; JInternalFrame internal = new JInternalFrame("Open",true,true,true,true); desktop.add(internal); JButton button = new JButton("Open"); button.addActionListener(showModal); Container iContent = internal.getContentPane(); iContent.add(button, BorderLayout.CENTER); internal.setBounds(25, 25, 200, 100); internal.setVisible(true); Container content = frame.getContentPane(); content.add(desktop, BorderLayout.CENTER); frame.setSize(500, 300); frame.setVisible(true); }}文件2---ModalFrame.java///////////////////////ModalFrame.java///////////////////////package modalframe;import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;import java.beans.*;public class ModalFrame extends JInternalFrame{public ModalFrame(String title, JRootPane rootPane, Component desktop){ super(title,true,true,true,true); // create opaque glass pane final JPanel glass = new JPanel(); glass.setOpaque(false); // Attach mouse listeners MouseInputAdapter adapter = new MouseInputAdapter(){}; glass.addMouseListener(adapter); glass.addMouseMotionListener(adapter); // Define close behavior PropertyChangeListener pcl = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { if (isVisible() &&event.getPropertyName().equals("closed")) { ModalFrame.this.setVisible(false); glass.setVisible(false); } } }; addPropertyChangeListener(pcl); try { setSelected(true); } catch (PropertyVetoException ignored) { } // Add modal internal frame to glass pane glass.add(this); // Change glass pane to our panel rootPane.setGlassPane(glass); // Show glass pane, then modal dialog glass.setVisible(true); // Add in option pane // Size frame Dimension size = getPreferredSize(); Dimension rootSize = desktop.getSize(); setBounds((rootSize.width - size.width) / 2, (rootSize.height - size.height) / 2, size.width, size.height); desktop.validate(); Create(); } public void setVisible(boolean value) { super.setVisible(value); if (value) { startModal(); } else { stopModal(); } } private synchronized void startModal() { try { if (SwingUtilities.isEventDispatchThread()) { EventQueue theQueue = getToolkit().getSystemEventQueue(); while (isVisible()) { AWTEvent event = theQueue.getNextEvent(); Object source = event.getSource(); if (source==statusCombo) { System.out.println("Combo"); } if (event instanceof ActiveEvent) { ((ActiveEvent)event).dispatch(); } else if (source instanceof Component) { ((Component)source).dispatchEvent( event); } else if (source instanceof MenuComponent) { ((MenuComponent)source).dispatchEvent( event); } else { System.err.println( "Unable to dispatch: " + event); } } } else { while (isVisible()) { wait(); } } } catch (InterruptedException ignored) { } } private synchronized void stopModal() { notifyAll(); } private boolean Create() { //create statusCombo = new JComboBox(); statusCombo.addItem("up"); statusCombo.addItem("down"); JPanel panelx=new JPanel(); //layout panelx.add(new JLabel("1")); panelx.add(new JLabel("2")); panelx.add(new JLabel("3")); panelx.add(new JLabel("4")); panelx.add(statusCombo); getContentPane().add(panelx,"Center"); return true; }private JComboBox statusCombo;} 各位大大,再过两天,JComboBox不能正常工作的这个问题没办法解决,我也一样给分,呵呵.如果解决了,我再开帖子给200分. 问一个另外的问题:在JInternalFrame中可以使用JSplitPane吗?你上面提到的:“这个InternalFrame是Toppest”是什么意思?和我问的问题有没有什么关系? JComboBox不是不能正常工作,而是当你的鼠标事件点击到模态JInternalFrame之外的地方都被截获没有发出去,所以不能正常工作。只要让他的下啦范围在你的模态JInternalFrame之内就不会出现问题。 关于J2SE中的传值与传引用的测试,大家试一试啊! 。发现了一个奇怪的问题,1.20+1.15居然得2.3499999999999996 正则表达式-后向引用? 关于java ping程序统计发送包的成功率 窗体怎么关 怎么让Java每过10分钟执行段程序? 帮忙看下这些代码有什么错 新手问题???? 小弟一点不懂Java!请教!!! 求教,Stateless session Bean会自动保存状态? 高分求教:如何熟练使用jbuilder下 dbswing中的jdbtable控件??在线等 那请问过载和重载的区别是什么?
再则,那样的外观也不符合我的要求.
package accessible;import javax.accessibility.*;
import javax.swing.*;
import java.awt.*;class CustomInternalFrame extends JInternalFrame {
public boolean isModel = false;
public CustomInternalFrame(String str,boolean a,boolean b,boolean c,boolean d){
super(str,a,b,c,d);
} public synchronized void startModal()
{
System.out.println("startModa");
if(isVisible() && !isShowing())
{
System.out.println("isSho");
for(Container container = super.getParent(); container != null; container = container.getParent())
if(!container.isVisible())
container.setVisible(true); }
try
{
if(SwingUtilities.isEventDispatchThread())
{
System.out.print("isEventDispatchThread");
EventQueue eventqueue = getToolkit().getSystemEventQueue();
while(isVisible())
{
AWTEvent awtevent = eventqueue.getNextEvent();
Object obj = awtevent.getSource();
if(awtevent instanceof ActiveEvent)
((ActiveEvent)awtevent).dispatch();
else
if(obj instanceof Component)
((Component)obj).dispatchEvent(awtevent);
else
if(obj instanceof MenuComponent)
((MenuComponent)obj).dispatchEvent(awtevent);
else
System.err.println("unable to dispatch event: " + awtevent);
}
} else
{
System.out.print("wait");
for(; isVisible(); wait());
}
}
catch(InterruptedException interruptedexception) { }
isModel = true;
} public synchronized void stopModal()
{
super.notifyAll();
isModel = true;
}}
{
JOptionPane joptionpane = new JOptionPane(obj, i, 2, icon1, null, null);
joptionpane.setWantsInput(true);
joptionpane.setSelectionValues(aobj);
joptionpane.setInitialSelectionValue(obj1);
JInternalFrame jinternalframe = joptionpane.createInternalFrame(component, s);
joptionpane.selectInitialValue();
jinternalframe.setVisible(true);
jinternalframe.startModal();
Object obj2 = joptionpane.getInputValue();
if(obj2 == UNINITIALIZED_VALUE)
return null;
else
return (String)obj2;
} public JInternalFrame createInternalFrame(Component component, String s)
{
Object obj = getDesktopPaneForComponent(component);
if(obj == null && (component == null || (obj = component.getParent()) == null))
throw new RuntimeException("JOptionPane: parentComponent does not have a valid parent");
final JInternalFrame iFrame = new JInternalFrame(s, false, false, false, false);
iFrame.putClientProperty("JInternalFrame.frameType", "optionDialog");
addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent propertychangeevent)
{
if(iFrame.isVisible() && propertychangeevent.getSource() == JOptionPane.this && (propertychangeevent.getPropertyName().equals("value") || propertychangeevent.getPropertyName().equals("inputValue")))
{
try
{
iFrame.setClosed(true);
}
catch(PropertyVetoException propertyvetoexception1) { }
iFrame.setVisible(false);
iFrame.stopModal();
}
} });
iFrame.getContentPane().add(this, "Center");
if(obj instanceof JDesktopPane)
((Container) (obj)).add(iFrame, JLayeredPane.MODAL_LAYER);
else
((Container) (obj)).add(iFrame, "Center");
Dimension dimension = iFrame.getPreferredSize();
Dimension dimension1 = ((Component) (obj)).getSize();
iFrame.setBounds((dimension1.width - dimension.width) / 2, (dimension1.height - dimension.height) / 2, dimension.width, dimension.height);
((Container) (obj)).validate();
try
{
iFrame.setSelected(true);
}
catch(PropertyVetoException propertyvetoexception) { }
return iFrame;
}
[email protected]
你可以直接另写一个类把这两个方法改为公用的,然后参考JOption的方法来用它。原码我已经反编了,给你发过去。
但结果发现如果上面放了个JComboBox,JComboBox不能正常工作.
原因应该是这个InternalFrame是Toppest,而点击ComboBox时弹出了一个新的窗口...这样,就选不到这个新弹出的窗口了(ComboBox弹出的).
原代码:
文件1------------------Modal.java
///////Modal.java/////////////////////
package modalframe;import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.beans.*;public class Modal
{
public static void main(String args[])
{
final JFrame frame = new JFrame("Main");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JDesktopPane desktop = new JDesktopPane();
ActionListener showModal =
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
// Construct a message internal frame popup
JInternalFrame iFrame =
new ModalFrame("Really Modal",frame.getRootPane(), desktop);
iFrame.setVisible(true);
}
}; JInternalFrame internal =
new JInternalFrame("Open",true,true,true,true);
desktop.add(internal); JButton button = new JButton("Open");
button.addActionListener(showModal); Container iContent = internal.getContentPane();
iContent.add(button, BorderLayout.CENTER);
internal.setBounds(25, 25, 200, 100);
internal.setVisible(true); Container content = frame.getContentPane();
content.add(desktop, BorderLayout.CENTER);
frame.setSize(500, 300);
frame.setVisible(true);
}
}
文件2---ModalFrame.java
///////////////////////ModalFrame.java///////////////////////
package modalframe;import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.beans.*;public class ModalFrame extends JInternalFrame
{
public ModalFrame(String title, JRootPane rootPane, Component desktop)
{
super(title,true,true,true,true);
// create opaque glass pane
final JPanel glass = new JPanel();
glass.setOpaque(false);
// Attach mouse listeners
MouseInputAdapter adapter =
new MouseInputAdapter(){};
glass.addMouseListener(adapter);
glass.addMouseMotionListener(adapter);
// Define close behavior
PropertyChangeListener pcl =
new PropertyChangeListener()
{
public void propertyChange(PropertyChangeEvent event)
{
if (isVisible() &&event.getPropertyName().equals("closed"))
{
ModalFrame.this.setVisible(false);
glass.setVisible(false);
}
}
};
addPropertyChangeListener(pcl); try {
setSelected(true);
} catch (PropertyVetoException ignored) {
}
// Add modal internal frame to glass pane
glass.add(this);
// Change glass pane to our panel
rootPane.setGlassPane(glass);
// Show glass pane, then modal dialog
glass.setVisible(true);
// Add in option pane
// Size frame
Dimension size = getPreferredSize();
Dimension rootSize = desktop.getSize();
setBounds((rootSize.width - size.width) / 2,
(rootSize.height - size.height) / 2,
size.width, size.height);
desktop.validate();
Create(); }
public void setVisible(boolean value) {
super.setVisible(value);
if (value) {
startModal();
} else {
stopModal();
}
} private synchronized void startModal() {
try {
if (SwingUtilities.isEventDispatchThread()) {
EventQueue theQueue =
getToolkit().getSystemEventQueue();
while (isVisible()) {
AWTEvent event = theQueue.getNextEvent();
Object source = event.getSource();
if (source==statusCombo)
{
System.out.println("Combo");
}
if (event instanceof ActiveEvent) {
((ActiveEvent)event).dispatch();
} else if (source instanceof Component) {
((Component)source).dispatchEvent(
event);
} else if (source instanceof MenuComponent) {
((MenuComponent)source).dispatchEvent(
event);
} else {
System.err.println(
"Unable to dispatch: " + event);
}
}
} else {
while (isVisible()) {
wait();
}
}
} catch (InterruptedException ignored) {
}
} private synchronized void stopModal() {
notifyAll();
} private boolean Create()
{
//create
statusCombo = new JComboBox();
statusCombo.addItem("up");
statusCombo.addItem("down");
JPanel panelx=new JPanel();
//layout
panelx.add(new JLabel("1"));
panelx.add(new JLabel("2"));
panelx.add(new JLabel("3"));
panelx.add(new JLabel("4"));
panelx.add(statusCombo);
getContentPane().add(panelx,"Center");
return true;
}
private JComboBox statusCombo;
}
如果解决了,我再开帖子给200分.
你上面提到的:“这个InternalFrame是Toppest”是什么意思?和我问的问题有没有什么关系?