2013-04-12 146 views
0

我有一個JFrame,在其中刪除並添加組件,每次我執行此操作時,都會相應地調整框架大小。我添加了一個組件監聽器,但它當然是由用戶調整窗口大小和setSize()方法觸發的。
有沒有辦法從ComponentEvent看到用戶是調整窗口大小還是通過setSize()完成的?我發現的可能的解決方案是:
1.使用一個標誌 - 布爾型調整大小 - 我在setSize()之前設置爲true,之後設置爲false。
2.添加一個mouseDragged偵聽器,並比較拖動前後的大小。
第二個絕對不是一個好選擇。第一個會工作,但我想知道我能否以簡單的方式找到用戶是否是調整窗口大小的人。Java ComponentResized - 檢測用戶是調整窗口大小還是以編程方式調整大小

+1

我肯定會設置標誌,這是最簡單的。 –

+1

檢查在窗口調整大小事件之前是否有鼠標事件:) –

+1

嘗試檢查'event instanceof MouseEvent' ...在兩種情況下是否有不同的出現? – The111

回答

3

的I調整框架相應

的哪些錯誤使用包()?

我刪除和添加組件,每次我這樣做的時候,

那麼這就是你應該設置你的布爾值:

programResize == true: 
panel.add(...); 
frame.setSize(...); // this should cause the ComponentListener to fire 
// the ComponentListener would then use programResize == false; 

或者是更好的選擇的選擇可能是:

component.removeComponentListener(...); 
panel.add(...); 
frame.setSize(...); 
component.addComponentListener(...); 

我更喜歡這種方法,因爲所有基於人的邏輯ual更新是自包含在一個地方,並且不需要定義布爾變量。

+0

+1最後「選項選項」:-) – mKorbel

+0

事實上,最後一個建議很好。包裝對於這個框架並不是真正的選擇,因爲它是如何完成的。不過,我想知道聽者內部是什麼樣的事件,但似乎不可能:) –

1

有沒有辦法從ComponentEvent看到用戶 調整窗口的大小還是通過setSize()完成的?

是的,它是使用由搖擺定時器

  • reseted布爾標誌的情況下用戶調整窗口,然後的ComponentListener觸發事件的每每一個像素一個新的事件,一羣

  • 通過確定集合集(Xxx)大小是此事件僅被觸發一次

有關事件的示例從ComponentListner

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.util.Vector; 

public class ComponentEventDemo extends JPanel 
     implements ComponentListener, HierarchyListener, 
     ItemListener { 

    private JFrame frame; 
    private static final long serialVersionUID = 1L; 
    private JTextArea display; 
    private JLabel label; 
    private JButton button = new JButton("Change Size"); 
    private String newline = "\n"; 

    public ComponentEventDemo() { 
     display = new JTextArea(); 
     display.setEditable(false); 
     JScrollPane scrollPane = new JScrollPane(display); 
     scrollPane.setPreferredSize(new Dimension(350, 200)); 
     label = new JLabel("This is a label", JLabel.CENTER); 
     label.addComponentListener(this); 
     JCheckBox checkbox = new JCheckBox("Label visible", true); 
     checkbox.addItemListener(this); 
     checkbox.addComponentListener(this); 
     button.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       Dimension dim = frame.getPreferredSize(); 
       if (!dim.equals(new Dimension(800, 600))) { 
        frame.setPreferredSize(new Dimension(800, 600)); 
        frame.pack(); 
       } else { 
        frame.setPreferredSize(new Dimension(400, 300)); 
        frame.pack(); 
       } 
      } 
     }); 
     JPanel panel = new JPanel(new GridLayout(1, 3)); 
     panel.add(label); 
     panel.add(checkbox); 
     panel.add(button); 
     panel.addComponentListener(this); 
     frame = new JFrame("ComponentEventDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(scrollPane, BorderLayout.CENTER); 
     frame.add(panel, BorderLayout.PAGE_END); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    @Override 
    public void itemStateChanged(ItemEvent e) { 
     if (e.getStateChange() == ItemEvent.SELECTED) { 
      label.setVisible(true); 
      label.revalidate(); 
      label.repaint(); 
     } else { 
      label.setVisible(false); 
     } 
    } 

    protected void displayMessage(String message) { 
     //If the text area is not yet realized, and 
     //we tell it to draw text, it could cause 
     //a text/AWT tree deadlock. Our solution is 
     //to ensure that the text area is realized 
     //before attempting to draw text. 
     // if (display.isShowing()) { 
     display.append(message + newline); 
     display.setCaretPosition(display.getDocument().getLength()); 
     //} 
    } 

    @Override 
    public void componentHidden(ComponentEvent e) { 
     //displayMessage(e.getComponent().getClass().getName() + " --- Hidden"); 
    } 

    @Override 
    public void componentMoved(ComponentEvent e) { 
     //displayMessage(e.getComponent().getClass().getName() + " --- Moved"); 
    } 

    @Override 
    public void componentResized(ComponentEvent e) { 
     displayMessage(e.getComponent().getClass().getName() + " --- Resized "); 
    } 

    @Override 
    public void componentShown(ComponentEvent e) { 
     //displayMessage(e.getComponent().getClass().getName() + " --- Shown"); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       ComponentEventDemo componentEventDemo = new ComponentEventDemo(); 
      } 
     }); 
    } 

    @Override 
    public void hierarchyChanged(HierarchyEvent e) { 
     displayMessage(e.getComponent().getClass().getName() + " --- Hierarchy changed"); 
    } 
} 
+0

感謝您花時間回答。你的回答很混亂。我的意思是你告訴我使用一個計時器,但給我一個一般的例子。我知道如何使用監聽器,並且我沒有發佈任何代碼的原因是它本來是無用的,因爲我想要的只是一個使setSize()在componentResized()中傳遞的條件。另外,我不想爲此添加計時器。它不覺得正確:) –

+0

'我的意思是你告訴我使用一個Timer,但給我一個通用的例子',不是這個例子包含幾個老的常規Swing Bugs,一個用JCheckBox可以在Java6/7中模擬,回到定時器,請您如何分配一個對象,一次(從ComponentListener)在用戶調整容器的情況下,通過使用mouse_dragged,有回答您的問題, – mKorbel