2011-08-23 24 views
2

當前我可以通過按下「添加」JButton將一些定製組件對象添加到JPanel。我還得到了一個「刪除」JButton,我希望與「add」做相反的操作。java刪除組件

我的意圖是,我可以用鼠標選擇一個組件,然後單擊刪除按鈕,然後pressto!,組件就消失了。

我將一個MouseListener掛鉤到面板,並使用MouseEvent,e.getComponent()獲取鼠標點擊的當前組件。因此,如果它返回一個自定義組件,那麼變量「private myComponent current」(已設置爲null)將指向該組件。然後我可以點擊「刪除」按鈕將其刪除。一個actionListener已經添加在「刪除」按鈕中,並在主體中調用this.remove(current)(如果current不爲null)。

但是,這不起作用,因爲我不能刪除組件!任何指針?

如果有一種優雅的方式來管理添加/刪除組件,請建議!

public class MainDisplayPanel extends JPanel implements ActionListener, MouseListener{ 

private JButton newClassButton; 
private JButton deleteButton; 
private Resizable current; 
private Resizable resizer; 
public MainDisplayPanel(LayoutManager layout) { 
    super(layout); 

    newClassButton.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
      addResizer(); 
    }   
    }); 

    deleteButton = new JButton("Delete"); 
    deleteButton.addActionListener(this); 
    this.addMouseListener(this); 
    this.add(newClassButton); 
    this.add(deleteButton); 

} 
public void addResizer() { 
    //JPanel panel = new JPanel(); 
    //panel.setBackground(Color.white); 
    resizer = new Resizable(new ClassBox()); 
    this.add(resizer); 
    this.revalidate(); 
    this.repaint(); 
} 

public void actionPerformed(ActionEvent e) { 
      if(current!=null) 
      { 
       this.remove(current); 
       this.revalidate(); 
       this.repaint(); 

      } 
} 

public void mouseClicked(MouseEvent e) { 
    System.out.println(e); 
      Component component = e.getComponent(); 

      if(component instanceof Resizable) 
       current= (Resizable) e.getComponent(); 

} 


    public static void main(String[] args) { 
    JFrame jframe = new JFrame(); 
    jframe.add(new MainDisplayPanel(null)); 
    jframe.setSize(new Dimension(600,400)); 
    jframe.setVisible(true); 
    jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 

} Doh!

現在,在addResizer()方法中。每次按下添加按鈕添加一個新的可調整大小的對象時,之前添加的對象發生了什麼?我敢肯定,他們成爲null因爲resizer變量不再引用它們?即使情況如此,他們仍然顯示在面板上...如果我按刪除,只有新添加的Resizable對象被刪除。那麼我在這裏的正確軌道?

編輯:總結我的問題,我迷上了MouseListener錯誤的對象。它應該是可調整大小的對象而不是面板。因此,可變電流始終爲空。

+0

一點很難說沒有一些代碼的確切的問題,但我的猜測是某種範圍界定問題(特別是與任何匿名聽衆)的。否則,我認爲這大致是我想要的...... –

+0

是的,我使用匿名聽衆。也添加了一些代碼。 – bili

回答

3

你的問題是你的MouseLisetener。您正在監聽MainDisplayPanel,因此當您單擊JPanel時,mousePressed方法中由e返回的MouseEvent#getComponent方法將返回MainDisplayPanel實例,因爲這是正在監聽的內容,而不是可調整的實例在鼠標下。

解決方案包括:

  • 創建一個MouseListener的對象,並使用您的當前設置添加此相同的對象,以每個能夠調整大小的MouseListener的可調整大小,或
  • ,但握住你的可調整的在一個ArrayList和然後遍歷mousePressed方法中的數組列表,以查看是否使用componentAt(...)方法單擊了任何可調整大小。

請注意,我不得不創建自己的SSCCE來解決這個問題。再次在將來,請大家幫忙,爲我們做這件事,因爲它確實符合您和我們的最佳利益,並表明您尊重我們的時間和我們的幫助。

編輯1
我SSCCE:

import java.awt.*; 
import java.awt.event.*; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class MainDisplayPanel extends JPanel { 
    private static final int RESIZABLE_COUNT = 40; 
    private JButton deleteButton; 
    private Resizable current; 
    private Resizable resizer; 
    private List<Resizable> resizableList = new ArrayList<Resizable>(); 

    public MainDisplayPanel(LayoutManager layout) { 
     super(layout); 

     deleteButton = new JButton("Delete"); 
     deleteButton.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      deleteButtonActionPerformed(e); 
     } 
     }); 
     this.addMouseListener(new MyMouseAdapter()); 
     this.add(deleteButton); 

     for (int i = 0; i < RESIZABLE_COUNT; i++) { 
     addResizer(); 
     } 
    } 

    private void deleteButtonActionPerformed(ActionEvent e) { 
     if (current != null) { 
     this.remove(current); 
     resizableList.remove(current); 
     current = null; 
     this.revalidate(); 
     this.repaint(); 
     } 
    } 

    public void addResizer() { 
     resizer = new Resizable(); 
     this.add(resizer); 
     resizableList.add(resizer); 
     this.revalidate(); 
     this.repaint(); 
    } 

    private class MyMouseAdapter extends MouseAdapter { 

     @Override 
     public void mousePressed(MouseEvent e) { 
     current = null; 
     Component c = getComponentAt(e.getPoint()); 
     for (Resizable resizable : resizableList) { 
      if (resizable == c) { 
       current = resizable; 
       resizable.setFill(true); 
      } else { 
       resizable.setFill(false); 
      } 
     } 
     } 
    } 

    public static void main(String[] args) { 
     JFrame jframe = new JFrame(); 
     // !! jframe.add(new MainDisplayPanel(null)); 
     jframe.add(new MainDisplayPanel(new FlowLayout())); 
     jframe.setSize(new Dimension(600, 400)); 
     jframe.setVisible(true); 
     jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

} 

@SuppressWarnings("serial") 
class Resizable extends JPanel { 

    private static final int RESIZE_WIDTH = 50; 
    private static final int RESIZE_HEIGHT = 40; 
    private static final int THICKNESS = 5; 
    private static final Color FILL_COLOR = Color.pink; 

    public Resizable() { 
     Random rand = new Random(); 

     // different color border so we can see that it was the clicked one that was deleted. 
     Color color = new Color(
       rand.nextInt(255), 
       rand.nextInt(255), 
       rand.nextInt(255)); 
     setBorder(BorderFactory.createLineBorder(color, THICKNESS)); 
    } 

    @Override // so we can see it 
    public Dimension getPreferredSize() { 
     return new Dimension(RESIZE_WIDTH, RESIZE_HEIGHT); 
    } 

    public void setFill(boolean fill) { 
     Color fillColor = fill ? FILL_COLOR : null; 
     setBackground(fillColor); 
     repaint(); 
    } 

} 
+0

@bili:參見**編輯1 **代碼示例 –

+0

您如何做到這一點+1 – mKorbel

+0

謝謝氣墊船!我在addResizer()中添加了一個MouseListener來調整變量大小,因此每次單擊鼠標時,它都會將當前設置爲resizer並且它可以工作!我沒有發佈EECS的原因是我承認我很懶惰。但原因是我沒有考慮將Resizer縮減到單個JPanel類。會發生什麼情況是Resizer構造函數接受一個對象,並且此對象包含其他對象,而這些對象又將另一個對象與一組使用ActionListener和MouseListener的自定義組件綁定在一起。有些代碼使用FactoryMethod,所以整個代碼很長。 – bili

2

我相信問題是您需要強制Swing在移除組件後再次佈局組件。刪除(當前)後,調用revalidate()。

+0

'重新驗證',然後'重新繪製'後者,特別是如果一個組件被刪除。 –

+0

是的,我確實使用它們,但問題似乎沒有得到解決。 – bili

+0

然後,你有一個錯誤,也許是錯誤的參考 - 因爲你試圖刪除的JPanel不是一開始就添加的那個,但是誰知道,因爲我們無法編譯或運行你的代碼。我建議你創建併發佈一個[SSCCE](http://sscce.org)(請點擊並查看鏈接),我們將處於一個更好的位置,能夠給你真正的幫助,而不是愚蠢的狂野猜測。 –

3

很瘋狂的想法,但一切皆有可能,但在您使用一些LayoutManager奠定JComponent你可以從Container刪除JComponents和thenafter你必須/必須調用revalidate() + repaint()情況下

1) ,但這一行動有副作用 - >ReLayout Container然後集裝箱的內容可以非常期待***

2)在你AbsoluteLayout奠定Container情況下,這應該是最好的可能,但問題是如何與emtpy小號裏面Container

有很簡單的方法怎麼辦呢步伐,你需要在RightMouseClick你必須添加JPopupMenuContainer

  • 下,對MouseCursor

  • 然後打電話找JComponentContainer#remove(myComponent),然後您必須致電revalidate() + repaint()進行刷新GUI

或者是相同的,我

+0

bigPane包含2個其他JPanel,mainDisplayPane是其中之一,並使用null佈局管理器初始化,因爲我的定製組件可以在任何地方拖動和調整大小。其他窗格就在工具欄中。我會嘗試彈出菜單,看看是否有幫助。 – bili

+0

@bili然後結果在這裏http://stackoverflow.com/questions/7062154/java-define-unit-component-for-mouse-events最後的代碼由@dacwe關於'組件組件= SwingUtilities.getDeepestComponentAt(...) '應該爲那個 – mKorbel

+0

工作,那個鏈接的代碼對我來說看起來很可怕。如果我真的無法用其他方式解決這個問題,我會盡量不要訴諸它。謝謝你! – bili