透明的JPanels

时间:2011-10-16 16:40:54

标签: java swing jpanel transparent translucency

我正在编写一个GUI,允许用户绘制图形,其中每个节点由扩展的jlabel表示,每个箭头应由具有透明背景的扩展Jpanel表示(setOpaque(false)),但我注意到了仅绘制(或至少可见)第一个“箭头面板”,而其他未显示。此外,在第一个箭头后添加的节点没有正确绘制:只有当我用鼠标移动它们时它们才会被绘制。所有元素都添加到具有null布局管理器的JPanel中。我知道如果我使用JLayeredPane可能是最好的,但我想知道是否还有其他解决方案。 编辑:这是我使用的类: 这是表示节点

的类
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Iterator;
import java.util.LinkedList;

import javax.swing.JLabel;

import se.diag.exc.EccezioneDaMostrare;
public class AreaNodo extends JLabel implements MouseListener,
    MouseMotionListener, Cloneable {

/**
 * 
 */
private static final long serialVersionUID = 1L;
protected boolean inCreazione;
protected Dimension size=new Dimension(100,40);
protected ObservableArea oss;
protected LinkedList<PannelloFreccia> collegamenti=new LinkedList<PannelloFreccia>();
protected LinkedList<EventoAreaListener> listeners=new LinkedList<EventoAreaListener>();
public AreaNodo(){
    super();
    setOpaque(true);
    addMouseListener(this);
    addMouseMotionListener(this);
    oss=new ObservableArea(this);
    inCreazione=true;
}
public AreaNodo clone(){
    AreaNodo areaClonata=new AreaNodo();
    areaClonata.setSize(this.size);
    Iterator<PannelloFreccia> i=collegamenti.iterator();
    while(i.hasNext()){
        areaClonata.aggiungiColl(i.next().clone());
    }
    Iterator<EventoAreaListener> i2=listeners.iterator();
    while(i2.hasNext()){
        areaClonata.addEventoAreaListener(i2.next());
    }
    return areaClonata;
}
public void setSize(Dimension d){
    size=new Dimension(d.width, d.height);
}
public void setInCreazione(boolean value){
    inCreazione=value;
}
public void addEventoAreaListener(EventoAreaListener l){
    if (!listeners.contains(l))
        listeners.add(l);
}
public void removeEventoAreaListener(EventoAreaListener l){
    listeners.remove(l);
}
public void lanciaEventoAreaFineCreazione(){
    EventoArea e=new EventoArea(this, MotivazioneEvento.FINE_CREAZIONE);
    Iterator<EventoAreaListener> i=listeners.iterator();
    while(i.hasNext())
        i.next().EventoAreaOccurred(e);
}
public void lanciaEventoAreaSelezionata(){
    EventoArea e=new EventoArea(this, MotivazioneEvento.SELEZIONE);
    System.out.println("lanciato evento area sel "+this.getText()+" "+this.getToolTipText());
    Iterator<EventoAreaListener> i=listeners.iterator();
    System.out.println(listeners.size());
    while(i.hasNext()){
        EventoAreaListener l=i.next();
        l.EventoAreaOccurred(e);
        System.out.println(l.toString());
    }
}
public void aggiungiColl(PannelloFreccia pf){
    collegamenti.add(pf);
}
public void removeSubscriber(AreaSubscriber a){
    oss.removeSubscriber(a);
}
public void addSubscriber(AreaSubscriber a){
    oss.addSubscriber(a);
}
public void aggiungiCollegamento(AreaNodo a) throws EccezioneDaMostrare{
    PannelloFreccia p=new PannelloFreccia(getParent().getSize(), this, a);
    System.out.println("chiamato aggiungiColl area");
    ControllerGUI.aggiungiCollegamento(this, a);
    getParent().add(p);
    p.setBounds(0,0,getParent().getWidth(), getParent().getHeight());
    p.paintImmediately(0,0,p.getWidth(), p.getHeight());
    aggiungiColl(p);
    a.aggiungiColl(p);
}
public Dimension getMinimumSize(){
    return size;
}
public Dimension getPreferredSize(){
    return size;
}
public Dimension getSize(){
    return size;
}
private void sposta(Point p){
    Point pNuovo=new Point(p.x+getLocation().x, p.y+getLocation().y);
    setLocation(pNuovo);
}
public void spostaAssoluto(Point p){
    setLocation(p);
}
@Override
public void mouseDragged(MouseEvent arg0) {
    Point p=arg0.getPoint();
    sposta(p);
    oss.notifica();
}

@Override
public void mouseMoved(MouseEvent arg0) {
    /*if(inCreazione){
        Point p=arg0.getPoint();
        sposta(p);
        oss.notifica();
        repaint();
    }
    */
}

@Override
public void mouseClicked(MouseEvent arg0) {
    if(inCreazione){
        inCreazione=false;
        lanciaEventoAreaFineCreazione();
    }
    else
        lanciaEventoAreaSelezionata();
}

@Override
public void mouseEntered(MouseEvent arg0) {
    Font f=getFont();
    f=f.deriveFont(1);
    this.setFont(f);

}

@Override
public void mouseExited(MouseEvent arg0) {
    Font f=getFont();
    f=f.deriveFont(0);
    this.setFont(f);

}

@Override
public void mousePressed(MouseEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void mouseReleased(MouseEvent arg0) {
    // TODO Auto-generated method stub

}

public Point getPuntoCollegamento(AreaNodo a){
    Point posA=a.getLocation();
    if(posA.x>getLocation().x+this.getWidth()){
        return(new Point(getLocation().x+getWidth(), getLocation().y+getHeight()/2));
    }
    else{
        if(posA.x>getLocation().x){
            if(posA.y<getLocation().y){
                return(new Point(getLocation().x+getWidth()/2, getLocation().y));
            }
            else
                return(new Point(getLocation().x+getWidth()/2, getLocation().y+getHeight()));
        }
        else{
            return (new Point(getLocation().x, getLocation().y+getHeight()/2));
        }
    }
}

public PannelloFreccia ricercaCollegamento(AreaNodo a){
    Iterator<PannelloFreccia> i=collegamenti.iterator();
    while(i.hasNext()){
        PannelloFreccia cur=i.next();
        if(cur.getArea2()==a || cur.getArea1()==a)
            return cur;
    }
    return null;
}
protected void rimuoviFreccia(PannelloFreccia p){
    collegamenti.remove(p);
}

public void svuota(){
    Iterator<PannelloFreccia> i=collegamenti.iterator();
    while(i.hasNext()){
        PannelloFreccia p=i.next();
        p.rimuoviDaSubscriber();
        if(p.getArea2()!=this){
            p.getArea2().cancellaCollegamento(this);
            rimuoviFreccia(p);
        }
        else{
            p.getArea1().cancellaCollegamento(this);
            rimuoviFreccia(p);
        }

    }
    listeners=new LinkedList<EventoAreaListener>();
}
public void cancellaCollegamento(AreaNodo a){
    PannelloFreccia p=ricercaCollegamento(a);
    if(p!=null){
        p.rimuoviDaSubscriber();
        rimuoviFreccia(p);
    }

}
public int hashCode(){
    return getText().hashCode();
}
public boolean equals(Object o){
    if(o==this) return true;
    if(!(o instanceof AreaNodo)) return false;
    AreaNodo a=(AreaNodo)o;
    return this.getText().equals(a.getText());
}
public Color getColoreNonSel(){
    return Color.WHITE;
}
    }

虽然这是箭头面板

import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JPanel;
public class PannelloFreccia extends JPanel implements AreaSubscriber {

/**
 * 
 */
private static final long serialVersionUID = 1L;
Freccia f;
AreaNodo area1;
AreaNodo area2;
public PannelloFreccia(Dimension d, AreaNodo a1, AreaNodo a2){
    setPreferredSize(d);
    area1=a1;
    area2=a2;
    aggiungiASubscriber();
    f=new Freccia(area1.getPuntoCollegamento(area2), area2.getPuntoCollegamento(area1));
    setOpaque(false);
}
@Override
public void update(AreaNodo a) {
    if (a==area1){
        f=new Freccia(area1.getPuntoCollegamento(area2), area2.getPuntoCollegamento(area1));
    }
    if(a==area2){
        f=new Freccia(area1.getPuntoCollegamento(area2), area2.getPuntoCollegamento(area1));
    }

    repaint();
}

public AreaNodo getArea2(){
    return area2;
}
public AreaNodo getArea1(){
    return area1;
}
public void aggiungiASubscriber(){
    area1.addSubscriber(this);
    area2.addSubscriber(this);
}
public void rimuoviDaSubscriber(){
    area1.removeSubscriber(this);
    area2.removeSubscriber(this);
}
public void paintComponent(Graphics g){
    g.clearRect(0, 0, getWidth(), getHeight());
    f.disegna(g);
}
public PannelloFreccia clone(){
    PannelloFreccia pannelloClonato=new PannelloFreccia(getPreferredSize(), area1.clone(), area2.clone());
    return pannelloClonato;
}
    }

这是我添加所有这些的JPanel

import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.LinkedList;

import javax.swing.JPanel;

import se.diag.control.clientspec.grafica.AreaNodo;
import se.diag.control.clientspec.grafica.AreaNodoO;
import se.diag.control.clientspec.grafica.ControllerGUI;
import se.diag.control.clientspec.grafica.EventoArea;
import se.diag.control.clientspec.grafica.EventoAreaListener;
import se.diag.control.clientspec.grafica.MotivazioneEvento;
import se.diag.control.clientspec.grafica.ObserverStato;
import se.diag.control.clientspec.grafica.PannelloDiagnosi;
public class PannelloInserim extends JPanel implements PannelloOp, PannelloDiagnosi, MouseMotionListener {

private boolean inCreazione=false;
private AreaNodo areaDaAggiungere=null;
private Selezione sel;
private ObserverStato btnDiag;
public PannelloInserim(ObserverStato btnDiag) {
    super();
    setLayout(null);
    setBackground(Color.WHITE);
    addMouseListener(this);
    addMouseMotionListener(this);
    ControllerGUI.addEventoAreaListener(this);
    sel=new Selezione();
    this.btnDiag=btnDiag;
}
public LinkedList<AreaNodo> getSelezione(){
    return sel;
}
public void setInCreazione(boolean value){
    inCreazione=value;
}
@Override
public void EventoAreaOccurred(EventoArea e) {
    AreaNodo a=(AreaNodo)e.getSource();
    MotivazioneEvento m=e.getMotivo();
    switch(m){
    case CREAZIONE:{
        areaDaAggiungere=a;
        setInCreazione(true);

    }
    break;
    case ELIMINAZIONE:{
        a.svuota();
        remove(a);
    }
    break;
    case FINE_CREAZIONE:{
        setInCreazione(false);
    }
    }
}
@Override
public void mouseClicked(MouseEvent arg0) {
    sel.svuota();

}
@Override
public void mouseEntered(MouseEvent arg0) {
    if(inCreazione){
        add(areaDaAggiungere);
        areaDaAggiungere.setBounds(arg0.getX(), arg0.getY(), areaDaAggiungere.getSize().width, areaDaAggiungere.getSize().height);
        areaDaAggiungere.setInCreazione(true);
        areaDaAggiungere.addEventoAreaListener(this);
        areaDaAggiungere.addEventoAreaListener(sel);
        if(areaDaAggiungere instanceof AreaNodoO){
            ((AreaNodoO)areaDaAggiungere).addObserverStato(btnDiag);
        }
    }
}
@Override
public void mouseExited(MouseEvent arg0) {
    // TODO Auto-generated method stub

}
@Override
public void mousePressed(MouseEvent arg0) {
    // TODO Auto-generated method stub

}
@Override
public void mouseReleased(MouseEvent arg0) {
    // TODO Auto-generated method stub

}
@Override
public PannelloMostraDiagnosi mostraDiagnosi() {
    return new PannelloMostraDiagnosi(this);

}
@Override
public void mouseDragged(MouseEvent arg0) {
    // TODO Auto-generated method stub

}
@Override
public void mouseMoved(MouseEvent arg0) {
    if(inCreazione){
        areaDaAggiungere.spostaAssoluto(arg0.getPoint());
    }
}

    }

这是表示pannelloInserim

中所选节点的数据结构
public class Selezione extends LinkedList<AreaNodo> implements EventoAreaListener {

private SelezionePublisher selPub;
public Selezione(){
    super();
    selPub=new SelezionePublisher();
}
public void aggiungiObserver(ObserverSelezione os){
    selPub.addObserverSelezione(os);
}
public void rimuoviObserver(ObserverSelezione os){
    selPub.removeObserverSelezione(os);
}
public boolean add(AreaNodo a){
    System.out.println("chiamato add");
    System.out.println(this.toString());
    if (contains(a)){
        remove(a);
        System.out.println("rimosso");
    }
    else
        if(size()==2){
            svuota();
            a.setBackground(a.getColoreNonSel());
            System.out.println("svuotata");
        }
        else{
            if(size()==1 && getFirst().ricercaCollegamento(a)==null){
                System.out.println("collegamento");
                try {
                    super.add(a);
                    getFirst().aggiungiCollegamento(getLast());
                } catch (EccezioneDaMostrare e) {
                    JOptionPane.showMessageDialog(get(0).getTopLevelAncestor(), e.getMessage());
                }
                finally{
                    svuota();
                }
            }
            else{
                System.out.println("aggiunta");
                super.add(a);
            }

        }
    selPub.notifica(isVuota(), isSingola(), isDoppia());
    return true;
}
private void aggiungi(AreaNodo a){
    System.out.println("Aggiungi");
    add(a);
}

public void svuota(){
    System.out.println("chiamato svuota");
    Iterator<AreaNodo> i=iterator();
    while (i.hasNext()){
        AreaNodo a=i.next();
        a.setBackground(a.getColoreNonSel());
        i.remove();
    }
    selPub.notifica(isVuota(), isSingola(), isDoppia());
}
public boolean isVuota(){
    return size()==0;
}
public boolean isSingola(){
    return size()==1;
}
public boolean isDoppia(){
    return size()==2;
}
@Override
public void EventoAreaOccurred(EventoArea e) {
    if(e.getMotivo()==MotivazioneEvento.SELEZIONE){
        aggiungi((AreaNodo)e.getSource());
        System.out.println("evento area "+e.getMotivo().toString());

    }

}
public String toString(){
    StringBuffer sb=new StringBuffer();
    int i=1;
    sb.append(this.size()+"\n");
    for(AreaNodo a:this){
        sb.append(i+" "+a.getText()+" "+a.getToolTipText()+"\n");
        i++;
    }
    return sb.toString();
}

}

这是在创建,删除或选择节点时触发的事件:

package se.diag.control.clientspec.grafica;

    import java.util.EventObject;

    public class EventoArea extends EventObject {

private MotivazioneEvento motivo;
public EventoArea(Object arg0, MotivazioneEvento m) {
    super(arg0);
    motivo=m;
}
public MotivazioneEvento getMotivo(){
    return motivo;
}

    }

这是该活动的动机:

package se.diag.control.clientspec.grafica;

    public enum MotivazioneEvento {
CREAZIONE{
    public String toString(){
        return "Area creata";

}
},
SELEZIONE{
    public String toString(){
        return "Area selezionata";
    }
},
ELIMINAZIONE{
    public String toString(){
        return "Area eliminata";
    }
},
FINE_CREAZIONE{
    public String toString(){
        return "Fine Creazione";
    }
}

    }

这是EventoArea的侦听器接口:

package se.diag.control.clientspec.grafica;

import java.util.EventListener;

public interface EventoAreaListener extends EventListener {

public void EventoAreaOccurred(EventoArea e);
}

这是一个Observer模式中使用箭头面板的类,以使它们跟随节点:

package se.diag.control.clientspec.grafica;

import java.util.LinkedList;

public class ObservableArea {

private LinkedList<AreaSubscriber> sub;
private AreaNodo area;
public ObservableArea(AreaNodo a){
    area=a;
    sub=new LinkedList<AreaSubscriber>();
}
public void notifica(){
    for(AreaSubscriber elem:sub)
        elem.update(area);
}
public void addSubscriber(AreaSubscriber a){
    sub.add(a);
}
public void removeSubscriber(AreaSubscriber a){
    sub.remove(a);
}
}

这是相对于此类的订阅者:

package se.diag.control.clientspec.grafica;

public interface AreaSubscriber {

public void update(AreaNodo a);
}

当选择了两个没有链接的节点时,Selezione调用aggiungiCollegamento,它创建一个新的箭头面板并将其添加到pannelloInserim。

1 个答案:

答案 0 :(得分:0)

没关系,我发现了什么错误:在箭头面板的paintComponent()方法中调用了clearRect()。删除该行后,箭头变为可见,其他组件也没有问题。