Não sei se foi claro a minha pergunta, mas vou expô-la em miúdos:
Eu precisava de JPanels expandiveis, de acordo com a necessidade do cliente.
A classe abaixo, resolveu parte do meu problema, no entanto, preciso colocar uma imagem
personalizada no lugar da que foi desenhada.
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 = { "Teste 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)
{
UIManager.put("OptionPane.yesButtonText", "Sim");
UIManager.put("OptionPane.noButtonText", "Não");
UIManager.put("OptionPane.cancelButtonText", "Cancela");
try{
//UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName() );
//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
//UIManager.setLookAndFeel("org.jvnet.substance.skin.SubstanceRavenGraphiteLookAndFeel");
} catch (Exception e) {
}
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 = 40, // localização do texto
PAD = 5; //localização da imagem
public ActionPanel(String text, MouseListener ml)
{
this.text = text; // seta o texto
addMouseListener(ml); // seta o evento mouselistener
font = new Font("sans-serif", Font.PLAIN, 12); // fonte do texto
selected = false;
setBackground(new Color(200,200,220)); // cor de fundo
setPreferredSize(new Dimension(200,20));
setBorder(BorderFactory.createRaisedBevelBorder()); // cria a borda
setPreferredSize(new Dimension(200,20)); // dimensões
createImages(); // desenha as imagens
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);
}
// método responsável por criar as imagens de expandir e esconder
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();
}
}
não tenho nem idéia de como posso alterar este código sem perder sua funcionalidade...