前两天看到了关于面板收缩与展开的实例,现在有几个疑问想请教各位高手:1、我要写一个BordeLayout的主程序,想把面板收缩与展开的部分布局在西侧,但不知如何调用这个程序,应该怎么处理??
2、程序中“level 1"等文字是绘图上去的,但是怎么才能把它们居中呢?
3、如何点击面板的任意部位都可收缩或展开面板,而不仅局限在三角型区域呢??
  
源程序如下:
import java.awt.*; 
import java.awt.event.*; 
import java.awt.font.*; 
import java.awt.image.BufferedImage; 
import javax.swing.*; public class ExpandingPanels extends MouseAdapter { 
ActionPanel[] aps; 
JPanel[] panels; public ExpandingPanels() { 
assembleActionPanels(); 
assemblePanels(); 
} public void mousePressed(MouseEvent e) { 
ActionPanel ap = (ActionPanel) e.getSource(); 
if (ap.target.contains(e.getPoint())) { 
ap.toggleSelection(); 
togglePanelVisibility(ap); 

} private void togglePanelVisibility(ActionPanel ap) { 
int index = getPanelIndex(ap); 
if (panels[index].isShowing()) 
panels[index].setVisible(false); 
else 
panels[index].setVisible(true); 
ap.getParent().validate(); 
} private int getPanelIndex(ActionPanel ap) { 
for (int j = 0; j < aps.length; j++) 
if (ap == aps[j]) 
return j; 
return -1; 
} private void assembleActionPanels() { 
String[] ids = { "level 1", "level 2", "level 3", "level 4" }; 
aps = new ActionPanel[ids.length]; 
for (int j = 0; j < aps.length; j++) 
aps[j] = new ActionPanel(ids[j], this); 
} private void assemblePanels() { 
GridBagConstraints gbc = new GridBagConstraints(); 
gbc.insets = new Insets(2, 1, 2, 1); 
gbc.weightx = 1.0; 
gbc.weighty = 1.0; 
JPanel p1 = new JPanel(new GridBagLayout()); 
gbc.gridwidth = gbc.RELATIVE; 
p1.add(new JButton("button 1"), gbc); 
gbc.gridwidth = gbc.REMAINDER; 
p1.add(new JButton("button 2"), gbc); 
gbc.gridwidth = gbc.RELATIVE; 
p1.add(new JButton("button 3"), gbc); 
gbc.gridwidth = gbc.REMAINDER; 
p1.add(new JButton("button 4"), gbc); 
JPanel p2 = new JPanel(new GridBagLayout()); 
gbc.gridwidth = 1; 
gbc.anchor = gbc.EAST; 
p2.add(new JLabel("enter"), gbc); 
gbc.anchor = gbc.WEST; 
p2.add(new JTextField(8), gbc); 
gbc.anchor = gbc.CENTER; 
p2.add(new JButton("button 1"), gbc); 
gbc.gridwidth = gbc.REMAINDER; 
p2.add(new JButton("button 2"), gbc); 
JPanel p3 = new JPanel(new BorderLayout()); 
JTextArea textArea = new JTextArea(8, 12); 
textArea.setLineWrap(true); 
p3.add(new JScrollPane(textArea)); 
JPanel p4 = new JPanel(new GridBagLayout()); 
addComponents(new JLabel("label 1"), new JTextField(12), p4, gbc); 
addComponents(new JLabel("label 2"), new JTextField(16), p4, gbc); 
gbc.gridwidth = 2; 
gbc.gridy = 2; 
p4.add(new JSlider(), gbc); 
gbc.gridy++; 
JPanel p5 = new JPanel(new GridBagLayout()); 
p5.add(new JButton("button 1"), gbc); 
p5.add(new JButton("button 2"), gbc); 
p5.add(new JButton("button 3"), gbc); 
p5.add(new JButton("button 4"), gbc); 
gbc.weighty = 1.0; 
gbc.fill = gbc.BOTH; 
p4.add(p5, gbc); 
panels = new JPanel[] { p1, p2, p3, p4 }; 
} private void addComponents(Component c1, Component c2, Container c, 
GridBagConstraints gbc) { 
gbc.anchor = gbc.EAST; 
gbc.gridwidth = gbc.RELATIVE; 
c.add(c1, gbc); 
gbc.anchor = gbc.WEST; 
gbc.gridwidth = gbc.REMAINDER; 
c.add(c2, gbc); 
gbc.anchor = gbc.CENTER; 
} private JPanel getComponent() { 
JPanel panel = new JPanel(new GridBagLayout()); 
GridBagConstraints gbc = new GridBagConstraints(); 
gbc.insets = new Insets(1, 3, 0, 3); 
gbc.weightx = 1.0; 
gbc.fill = gbc.HORIZONTAL; 
gbc.gridwidth = gbc.REMAINDER; 
for (int j = 0; j < aps.length; j++) { 
panel.add(aps[j], gbc); 
panel.add(panels[j], gbc); 
panels[j].setVisible(false); 

JLabel padding = new JLabel(); 
gbc.weighty = 1.0; 
panel.add(padding, gbc); 
return panel; 
} public static void main(String[] args) { 
ExpandingPanels test = new ExpandingPanels(); 
JFrame f = new JFrame(); 
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
f.getContentPane().add(new JScrollPane(test.getComponent())); 
f.setSize(360, 500); 
f.setLocation(200, 100); 
f.setVisible(true); 

} class ActionPanel extends JPanel { 
String text; 
Font font; 
private boolean selected; 
BufferedImage open, closed; 
Rectangle target; 
final int OFFSET = 30, PAD = 5; public ActionPanel(String text, MouseListener ml) { 
this.text = text; 
addMouseListener(ml); 
font = new Font("sans-serif", Font.PLAIN, 12); 
selected = false; 
setBackground(new Color(200, 200, 220)); 
setPreferredSize(new Dimension(200, 20)); 
setBorder(BorderFactory.createRaisedBevelBorder()); 
setPreferredSize(new Dimension(200, 20)); 
createImages(); 
setRequestFocusEnabled(true); 
} public void toggleSelection() { 
selected = !selected; 
repaint(); 
} protected void paintComponent(Graphics g) { 
super.paintComponent(g); 
Graphics2D g2 = (Graphics2D) g; 
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
RenderingHints.VALUE_ANTIALIAS_ON); 
int w = getWidth(); 
int h = getHeight(); 
if (selected) 
g2.drawImage(open, PAD, 0, this); 
else 
g2.drawImage(closed, PAD, 0, this); 
g2.setFont(font); 
FontRenderContext frc = g2.getFontRenderContext(); 
LineMetrics lm = font.getLineMetrics(text, frc); 
float height = lm.getAscent() + lm.getDescent(); 
float x = OFFSET; 
float y = (h + height) / 2 - lm.getDescent(); 
g2.drawString(text, x, y); 
} private void createImages() { 
int w = 20; 
int h = getPreferredSize().height; 
target = new Rectangle(2, 0, 20, 18); 
open = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
Graphics2D g2 = open.createGraphics(); 
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
RenderingHints.VALUE_ANTIALIAS_ON); 
g2.setPaint(getBackground()); 
g2.fillRect(0, 0, w, h); 
int[] x = { 2, w / 2, 18 }; 
int[] y = { 4, 15, 4 }; 
Polygon p = new Polygon(x, y, 3); 
g2.setPaint(Color.green.brighter()); 
g2.fill(p); 
g2.setPaint(Color.blue.brighter()); 
g2.draw(p); 
g2.dispose(); 
closed = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
g2 = closed.createGraphics(); 
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
RenderingHints.VALUE_ANTIALIAS_ON); 
g2.setPaint(getBackground()); 
g2.fillRect(0, 0, w, h); 
x = new int[] { 3, 13, 3 }; 
y = new int[] { 4, h / 2, 16 }; 
p = new Polygon(x, y, 3); 
g2.setPaint(Color.red); 
g2.fill(p); 
g2.setPaint(Color.blue.brighter()); 
g2.draw(p); 
g2.dispose(); 

}

解决方案 »

  1.   

    1.寫一個類似ExpandingPanels 這個的類  就能放到你的程序里了 
    2.final int OFFSET = 30, PAD = 5; 把offset的值變大就行了~
    3.target = new Rectangle(2, 0, 20, 18);  把里面的后兩個坐標值變大 就行了
      

  2.   

    第一个我试了下,还是没搞出来,郁闷
    能提供个源码不?简单点的就行
    2、改变offset的值是可以,但不一定恰取到能居中的值,一个一个试不现实吧?!有其他方法吗??
      

  3.   

    公司的网关有限制,发言过长就不可以了,所以也许分几次来回答你的问题吧
    问题1:
    先把private JPanel getComponent()改成public
    在你的frame的mainPanel中,用mainPanel.add(new JScrollPane(leftPanel.getComponent()),BorderLayout.WEST);
    leftPanel就是ExpandingPanels
      

  4.   

    问题2:
    这个程序是把ActivePanel的内容绘制上去的,其实不用也可以,
    你可以把paintComponent方法注释掉
    ActionPanel的构造函数修改成:
    setPreferredSize(new Dimension(200, 30));
    this.add(new JLabel(text));
    //createImages();
    然后,mousePressed的内容稍微修改下:
    ap.contains(e.getPoint())
      

  5.   

    这样的话你就可以在ActivePanel中使用swing的组件来达到你的效果,
    问题3:问题2的修改就解决了问题3。
    问题4:我要实现面板中各组件的事件响应,是要在你的这个程序里添加把?
    如果是现在的这个类的话,你要修改的地方还有好多
      

  6.   

    如果要实现通用性的话,建议你把ActivePanel的类抽出去,
    并且把ActivePanel展开后的Panel作为ActivePanel的一个引用,最好在保持一个
    类似如JFrame这样的引用,构造ExpandingPanels之前把ActivePanel的集合构造好,传递给ExpandingPanels,ExpandingPanels只实现点击的事件传递,然后有你写的ActivePanel来实现要如何处理事件,这样可能会好些
      

  7.   

    谢谢cowputer ,我已经解决问题了感谢给我的提示与帮助!!
      

  8.   

    谢谢cowputer ,我已经解决问题了感谢给我的提示与帮助!!
      

  9.   

    谢谢cowputer ,我已经解决问题了感谢给我的提示与帮助!!