2012-06-11 6 views
6

Tôi có một JPanel chứa một thanh công cụ JToolbar (bao gồm một vài nút không có văn bản) và JTable và tôi cần bật/tắt (làm cho các tiện ích bên trong không thể nhấp). Tôi đã thử điều này:Java Swing: Bật/Tắt tất cả các thành phần trong JPanel

JPanel panel = ....; 
for (Component c : panel.getComponents()) c.setEnabled(enabled); 

nhưng nó không hoạt động. Có một giải pháp tốt hơn và chung chung hơn để cho phép/vô hiệu hóa tất cả các thành phần bên trong trong một JPanel?

Tôi đã phần nào giải quyết vấn đề của tôi sử dụng JLayer bắt đầu từ ví dụ ở đây http://docs.oracle.com/javase/tutorial/uiswing/misc/jlayer.html:

layer = new JLayer<JComponent>(myPanel, new BlurLayerUI(false)); 
..... 
((BlurLayerUI)layer.getUI()).blur(...); // switch blur on/off 


class BlurLayerUI extends LayerUI<JComponent> { 
    private BufferedImage mOffscreenImage; 
    private BufferedImageOp mOperation; 

    private boolean blur; 

    public BlurLayerUI(boolean blur) { 
     this.blur = blur; 
     float ninth = 1.0f/9.0f; 
     float[] blurKernel = { 
      ninth, ninth, ninth, 
      ninth, ninth, ninth, 
      ninth, ninth, ninth 
     }; 
     mOperation = new ConvolveOp(
       new Kernel(3, 3, blurKernel), 
       ConvolveOp.EDGE_NO_OP, null); 
     } 

    public void blur(boolean blur) { 
     this.blur=blur; 
    firePropertyChange("blur", 0, 1); 
    } 

    @Override 
    public void paint (Graphics g, JComponent c) { 
     if (!blur) { 
      super.paint (g, c); 
      return; 
     } 

     int w = c.getWidth(); 
    int h = c.getHeight(); 



    if (w == 0 || h == 0) { 
     return; 
    } 

    // Only create the offscreen image if the one we have 
    // is the wrong size. 
    if (mOffscreenImage == null || 
      mOffscreenImage.getWidth() != w || 
      mOffscreenImage.getHeight() != h) { 
     mOffscreenImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
    } 

    Graphics2D ig2 = mOffscreenImage.createGraphics(); 
    ig2.setClip(g.getClip()); 
    super.paint(ig2, c); 
    ig2.dispose(); 

    Graphics2D g2 = (Graphics2D)g; 
    g2.drawImage(mOffscreenImage, mOperation, 0, 0); 
    } 

    @Override 
    public void applyPropertyChange(PropertyChangeEvent pce, JLayer l) { 
    if ("blur".equals(pce.getPropertyName())) { 
     l.repaint(); 
    } 
    } 

} 

tôi vẫn còn có 2 vấn đề:

1) Trong liên kết trên các sự kiện có liên quan đến con chuột duy nhất. Làm thế nào tôi có thể quản lý các sự kiện bàn phím?

2) Làm cách nào để tạo hiệu ứng "màu xám" thay cho làm mờ?

+0

Bạn có thể thiết lập khả năng hiển thị của bảng điều khiển trực tiếp bằng cách sử dụng 'panel.setVisible (false)' –

+0

setVisible (false) làm cho các thành phần " vô hình "nhưng thực sự tôi cần nó vẫn hiển thị nhưng có màu xám. – Randomize

+0

hiện chủ đề này có giúp ích gì không? http://stackoverflow.com/a/305551/1417974 –

Trả lời

2

bạn có thể che phủ toàn bộ Container/JComponent

  1. GlassPane khối bằng MouseEvents mặc định, nhưng không phải bàn phím, đòi hỏi tiêu thụ tất cả keyevents từ ToolKit

  2. JLayer (Java7) dựa trên JXLayer (Java6)

  3. không thể thấy lý do tại sao không hoạt động cho bạn

enter image description here

enter image description here

enter image description here

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JCheckBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.border.LineBorder; 

public class AddComponentsAtRuntime { 

    private JFrame f; 
    private JPanel panel; 
    private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack; 

    public AddComponentsAtRuntime() { 
     JButton b = new JButton(); 
     //b.setBackground(Color.red); 
     b.setBorder(new LineBorder(Color.black, 2)); 
     b.setPreferredSize(new Dimension(600, 20)); 
     panel = new JPanel(new GridLayout(0, 1)); 
     panel.add(b); 
     f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(panel, "Center"); 
     f.add(getCheckBoxPanel(), "South"); 
     f.setLocation(200, 200); 
     f.pack(); 
     f.setVisible(true); 
    } 

    private JPanel getCheckBoxPanel() { 
     checkValidate = new JCheckBox("validate"); 
     checkValidate.setSelected(false); 
     checkReValidate = new JCheckBox("revalidate"); 
     checkReValidate.setSelected(true); 
     checkRepaint = new JCheckBox("repaint"); 
     checkRepaint.setSelected(true); 
     checkPack = new JCheckBox("pack"); 
     checkPack.setSelected(true); 
     JButton addComp = new JButton("Add New One"); 
     addComp.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       JButton b = new JButton(); 
       //b.setBackground(Color.red); 
       b.setBorder(new LineBorder(Color.black, 2)); 
       b.setPreferredSize(new Dimension(400, 10)); 
       panel.add(b); 
       makeChange(); 
       System.out.println(" Components Count after Adds :" + panel.getComponentCount()); 
      } 
     }); 
     JButton removeComp = new JButton("Remove One"); 
     removeComp.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       int count = panel.getComponentCount(); 
       if (count > 0) { 
        panel.remove(0); 
       } 
       makeChange(); 
       System.out.println(" Components Count after Removes :" + panel.getComponentCount()); 
      } 
     }); 
     JButton disabledComp = new JButton("Disabled All"); 
     disabledComp.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (Component c : panel.getComponents()) { 
        c.setEnabled(false); 
       } 
      } 
     }); 
     JButton enabledComp = new JButton("Enabled All"); 
     enabledComp.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (Component c : panel.getComponents()) { 
        c.setEnabled(true); 
       } 
      } 
     }); 
     JPanel panel2 = new JPanel(); 
     panel2.add(checkValidate); 
     panel2.add(checkReValidate); 
     panel2.add(checkRepaint); 
     panel2.add(checkPack); 
     panel2.add(addComp); 
     panel2.add(removeComp); 
     panel2.add(disabledComp); 
     panel2.add(enabledComp); 
     return panel2; 
    } 

    private void makeChange() { 
     if (checkValidate.isSelected()) { 
      panel.validate(); 
     } 
     if (checkReValidate.isSelected()) { 
      panel.revalidate(); 
     } 
     if (checkRepaint.isSelected()) { 
      panel.repaint(); 
     } 
     if (checkPack.isSelected()) { 
      f.pack(); 
     } 
    } 

    public static void main(String[] args) { 
     AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime(); 
    } 
} 
+0

cảm ơn nhiều câu trả lời: 1) GlassPane là thú vị tho Tôi không biết làm thế nào để có được một hiệu ứng mờ hoặc xám. 2) Tôi đang làm việc với Java 6 và tôi không muốn (cho thời điểm này) sử dụng thư viện bên ngoài. 3) Giải pháp này có vấn đề với JTable. – Randomize

+0

1) không có vấn đề đặt có JLabel.setOpaque (false) và đặt ở đó một số màu (int, int, int, alpa), 2) JXLabel không phải là thư viện bên ngoài, đây là dự án cá nhân được chấp nhận là JLayer, 3) đặt JLabel vào (giống như trong điểm đầu tiên) JViewPort (Tôi hy vọng rằng JTable là thành JScrollPane) 4) yo có thể để kiểm tra bài viết của tôi GlassPane và JViewport gắn thẻ – mKorbel

+0

Tôi đang cố gắng với JLayer và tôi giải quyết một phần vấn đề. Vui lòng xem câu hỏi được chỉnh sửa lại của tôi. – Randomize

40

Nó đòi hỏi một cuộc gọi đệ quy.

Disable All In Container

import java.awt.*; 
import javax.swing.*; 

public class DisableAllInContainer { 

    public void enableComponents(Container container, boolean enable) { 
     Component[] components = container.getComponents(); 
     for (Component component : components) { 
      component.setEnabled(enable); 
      if (component instanceof Container) { 
       enableComponents((Container)component, enable); 
      } 
     } 
    } 

    DisableAllInContainer() { 
     JPanel gui = new JPanel(new BorderLayout()); 

     final JPanel container = new JPanel(new BorderLayout()); 
     gui.add(container, BorderLayout.CENTER); 

     JToolBar tb = new JToolBar(); 
     container.add(tb, BorderLayout.NORTH); 
     for (int ii=0; ii<3; ii++) { 
      tb.add(new JButton("Button")); 
     } 

     JTree tree = new JTree(); 
     tree.setVisibleRowCount(6); 
     container.add(new JScrollPane(tree), BorderLayout.WEST); 

     container.add(new JTextArea(5,20), BorderLayout.CENTER); 

     final JCheckBox enable = new JCheckBox("Enable", true); 
     enable.addActionListener(new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       enableComponents(container, enable.isSelected()); 
      } 
     }); 
     gui.add(enable, BorderLayout.SOUTH); 

     JOptionPane.showMessageDialog(null, gui); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable(){ 
      @Override 
      public void run() { 
       new DisableAllInContainer(); 
      } 
     }); 
    }} 
+0

Cảm ơn giải pháp đó rất gần với giải pháp của tôi. Nhưng nó có cùng một vấn đề: Tôi có một JTable và nếu bạn áp dụng setEnabled (false) vào nó, bảng trở thành không thể nhấp nhưng nó không phải là "grayed" đối diện với các thành phần còn lại. – Randomize

+0

Nó cũng có vấn đề, nếu một số thành phần trong vùng chứa đã được bật và bị vô hiệu hóa khác, thì tất cả chúng sẽ được đặt thành trạng thái được bật tương tự, ví dụ: Bạn không thể thực hiện bật và sau đó thực hiện hoàn tác. – user1062589

+1

khai báo enableComponents (...) tĩnh. chức năng tiện ích rất đẹp – Exceptyon

5

tôi đã sử dụng các chức năng sau:

void setPanelEnabled(JPanel panel, Boolean isEnabled) { 
    panel.setEnabled(isEnabled); 

    Component[] components = panel.getComponents(); 

    for(int i = 0; i < components.length; i++) { 
     if(components[i].getClass().getName() == "javax.swing.JPanel") { 
      setPanelEnabled((JPanel) components[i], isEnabled); 
     } 

     components[i].setEnabled(isEnabled); 
    } 
}