1

私のクラスは、選択した色が変わるたびにEvent Controllerからイベントを受信して​​いません。また、(星を描画するために使用しているもの) からも受信していません。私は徹底的にチェックしましたが、問題を見つけることができませんでした.これが私のコードです(便宜上、パッケージとインポートを省略しました):JColorChooserKeyEventsJComponent

public class Main {

public static void main(String[] args) {
    GestorDeEventos ge=new GestorDeEventos();

    Interfaz f=new Interfaz();

    ge.setVentana(f);
    f.setGestorEventos(ge);
}
}

public class Interfaz extends JFrame {

private GestorDeEventos miGestor;

private Container c;

AreaDeDibujos lienzo;

private JLabel lInfo,lCantidadPuntas,lTamanioEstrella,lLargoPuntas,lColor,lRotar;
JSpinner spinnerCantidadPuntas;
JSlider sliderTamanioEstrella;
DoubleJSlider sliderLargoPuntas;
JColorChooser ccColor;
JButton bRotarIzquierda,bRotarDerecha;
public Interfaz(){

    setTitle("Ejemplo <<Dibujo de primitivas y poligonos>> Version 1.1 (07/02/2013)");
    setSize(1024,720);
    setResizable(false);

    c=getContentPane();
    c.setBackground(new Color(240,250,245));
    c.setLayout(null);

    lienzo=new AreaDeDibujos(600,600);
    lienzo.setLocation(400,15);

    c.add(lienzo);

    // Para informar al usuario del proposito de dicha seccion de la interfaz
    lInfo=new JLabel("Por favor, seleccione los parametros de la estrella a dibujar:");
    lInfo.setBounds(10,10,350,20);
    c.add(lInfo);

    // Para seleccionar la cantidad de puntas de la estrella
    lCantidadPuntas=new JLabel("Numero de puntas de la estrella: ");
    lCantidadPuntas.setBounds(10,35,350,20);
    c.add(lCantidadPuntas);
    spinnerCantidadPuntas=new JSpinner(new SpinnerNumberModel(7, //valor inicial
                                                              Estrella.MINIMO_PUNTAS, //valor minimo
                                                              Estrella.MAXIMO_PUNTAS, //valor maximo
                                                              1 // incremento/decremento (paso)
                                                             )
                                       );
    spinnerCantidadPuntas.setBounds(10,55,120,20);
    /*
      En la siguiente linea deshabilito el campo de texto del JSPinner de modo que su valor
      solo pueda ser editado mediante los botones que incluye el propio JSpinner, esto lo hago
      para evitar que alguien coloque un valor fuera del rango [Estrella.MINIMO_PUNTAS, Estrella.MAXIMO_PUNTAS]
    */
    ((JSpinner.DefaultEditor)spinnerCantidadPuntas.getEditor()).getTextField().setEditable(false);
    c.add(spinnerCantidadPuntas);

    //Para seleccionar el tamaño de la estrella
    lTamanioEstrella=new JLabel("Tamaño de la estrella (pixeles): ");
    lTamanioEstrella.setBounds(10,80,350,20);
    c.add(lTamanioEstrella);
    sliderTamanioEstrella=new JSlider( 
                                     JSlider.HORIZONTAL,
                                     AreaDeDibujos.TAMANIO_ESTRELLA_MINIMO,
                                     AreaDeDibujos.TAMANIO_ESTRELLA_MAXIMO,
                                     (int)(AreaDeDibujos.TAMANIO_ESTRELLA_MAXIMO/2)
                                     );
    Hashtable etiquetasDelSlider1 = new Hashtable();
    int i,cantidadDeRayas,rango,paso,minimo,maximo,valorDeLaRaya;
    minimo=AreaDeDibujos.TAMANIO_ESTRELLA_MINIMO;
    maximo=AreaDeDibujos.TAMANIO_ESTRELLA_MAXIMO;
    rango=maximo-minimo;
    cantidadDeRayas=10;
    paso=rango/cantidadDeRayas;
    for(i=0;i<=cantidadDeRayas;i++){
        valorDeLaRaya=minimo+paso*i;
        etiquetasDelSlider1.put(new Integer (valorDeLaRaya), new JLabel(""+valorDeLaRaya));
    }
    sliderTamanioEstrella.setLabelTable( etiquetasDelSlider1 );
    sliderTamanioEstrella.setPaintLabels(true);
    sliderTamanioEstrella.setMajorTickSpacing(paso);
    sliderTamanioEstrella.setPaintTicks(true);
    sliderTamanioEstrella.setBounds(10,100,350,60);
    c.add(sliderTamanioEstrella);

    //Para seleccionar el largo de las puntas de la estrella (% con respecto al tamaño total de la estrella)
    lLargoPuntas= new JLabel("Largo de las puntas(%): ");
    lLargoPuntas.setToolTipText("(% con respecto al tamaño total de la estrella)");
    lLargoPuntas.setBounds(10,165,350,20);
    c.add(lLargoPuntas);

    sliderLargoPuntas=new DoubleJSlider(100, 900, 367, 1000);
    Hashtable etiquetasDelSlider2 = new Hashtable();
    minimo=100;
    maximo=900;
    rango=maximo-minimo;
    cantidadDeRayas=10;
    paso=rango/cantidadDeRayas;
    for(i=0;i<=cantidadDeRayas;i++){
        valorDeLaRaya=minimo+paso*i;
        etiquetasDelSlider2.put(new Integer (valorDeLaRaya), new JLabel(""+valorDeLaRaya/10));
    }
    sliderLargoPuntas.setLabelTable( etiquetasDelSlider2 );
    sliderLargoPuntas.setPaintLabels(true);
    sliderLargoPuntas.setMajorTickSpacing(paso);
    sliderLargoPuntas.setPaintTicks(true);
    sliderLargoPuntas.setBounds(10,185,350,60);
    c.add(sliderLargoPuntas);

    // Para seleccionar el color
    lColor=new JLabel("Color: ");
    lColor.setBounds(10,250,350,20);
    c.add(lColor);
    ccColor=new JColorChooser(new Color(0,255,255));
    ccColor.setPreviewPanel(new JPanel());
    JScrollPane spColor=new JScrollPane(ccColor);
    spColor.setBounds(10,270,350,250);
    c.add(spColor);

    //Para rotar la estrella
    lRotar=new JLabel("Rotar: ");
    lRotar.setBounds(10,525,350,20);
    c.add(lRotar);

    bRotarIzquierda=new JButton("<");
    bRotarIzquierda.setBounds(63,545,80,40);
    c.add(bRotarIzquierda);

    bRotarDerecha=new JButton(">");
    bRotarDerecha.setBounds(206,545,80,40);
    c.add(bRotarDerecha);

    setFocusable(true);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
}

public void setGestorEventos(GestorDeEventos ge){
    miGestor=ge;
    spinnerCantidadPuntas.addChangeListener(miGestor);
    sliderLargoPuntas.addChangeListener(miGestor);
    sliderTamanioEstrella.addChangeListener(miGestor);
    ccColor.getSelectionModel().addChangeListener(miGestor);

    bRotarDerecha.addActionListener(miGestor);
    bRotarIzquierda.addActionListener(miGestor);

    lienzo.addKeyListener(miGestor);
    /*addKeyListener(miGestor);
    spinnerCantidadPuntas.addKeyListener(miGestor);
    sliderLargoPuntas.addKeyListener(miGestor);
    sliderTamanioEstrella.addKeyListener(miGestor);
    ccColor.addKeyListener(miGestor);
    bRotarDerecha.addKeyListener(miGestor);
    bRotarIzquierda.addKeyListener(miGestor);*/
}

}

public class AreaDeDibujos extends JComponent {

public static final int TAMANIO_ESTRELLA_MINIMO=50,TAMANIO_ESTRELLA_MAXIMO=400;
private DibujoDeEstrella dibujo;

public AreaDeDibujos(int largo, int ancho){
    setFocusable(true);
    setSize(largo,ancho);
    setBackground(Color.WHITE);
}

@Override
public void paint(Graphics g){
    g.setColor(Color.WHITE);
    g.clearRect(0, 0, this.getWidth(), this.getHeight());
    if(dibujo!=null){
        g.setColor(dibujo.getColor());
        for(Polygon d: dibujo.getDibujos())
            g.fillPolygon(d);
    }        
}

public void pintarEstrella(DibujoDeEstrella d){
    dibujo=d;
    repaint();
}
}

public class GestorDeEventos implements ChangeListener,KeyListener,ActionListener {

Interfaz ventana;
AreaDeDibujos areaDeTrabajo;

DibujoDeEstrella dibujo;

public GestorDeEventos() {
}

public void setVentana(Interfaz ventana) {
    this.ventana = ventana;
    areaDeTrabajo= ventana.lienzo;
    dibujo=new DibujoDeEstrella(
                               new Estrella(
                                           ventana.sliderTamanioEstrella.getValue(),
                                           (int)ventana.spinnerCantidadPuntas.getValue(),
                                           ventana.sliderLargoPuntas.getScaledValue(),
                                           ventana.ccColor.getColor()
                                           )
                               );
    areaDeTrabajo.pintarEstrella(dibujo);
}

@Override
public void stateChanged(ChangeEvent e) {
    if(e.getSource()==ventana.sliderLargoPuntas){
        dibujo.setLargoDePuntas(ventana.sliderLargoPuntas.getScaledValue());
    }
    else if(e.getSource()==ventana.sliderTamanioEstrella){
        dibujo.setTamanio(ventana.sliderTamanioEstrella.getValue());

    }
    else if(e.getSource()==ventana.spinnerCantidadPuntas){
        dibujo.setCantidadPuntas((int)ventana.spinnerCantidadPuntas.getValue());

    }
    else if(e.getSource()==ventana.ccColor){
        dibujo.setColor(ventana.ccColor.getColor());
    }
    areaDeTrabajo.pintarEstrella(dibujo);
}

@Override
public void keyTyped(KeyEvent e) { //NO USADA, AL NO DECLARAR NADA ADENTRO ESTAMOS EFECTIVAMENTE
                                   //IGNORANDO TODOS LOS EVENTOS DE ESTE TIPO
}

@Override
public void keyPressed(KeyEvent e) {
    if(e.getKeyCode()==KeyEvent.VK_LEFT){
        dibujo.moverIzquierda();
    }
    else if(e.getKeyCode()==KeyEvent.VK_RIGHT){
        dibujo.moverDerecha();
    }
    else if(e.getKeyCode()==KeyEvent.VK_UP){
        dibujo.moverArriba();
    }
    else if(e.getKeyCode()==KeyEvent.VK_DOWN){
        dibujo.moverAbajo();
    }
    areaDeTrabajo.pintarEstrella(dibujo);
}

@Override
public void keyReleased(KeyEvent e) { //NO USADA, AL NO DECLARAR NADA ADENTRO ESTAMOS EFECTIVAMENTE
                                      //IGNORANDO TODOS LOS EVENTOS DE ESTE TIPO
}

@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource().equals(ventana.bRotarIzquierda)){
        dibujo.rotar(-1);
    }
    else if(e.getSource().equals(ventana.bRotarDerecha)){
        dibujo.rotar(1);
    }
    areaDeTrabajo.pintarEstrella(dibujo);
}

}

public class DibujoDeEstrella {

private Estrella miEstrella; //Aqui guardamos los datos de la estrella como tal (independiente de como la dibujaremos)

private LinkedList<Polygon> dibujos; //Esto es lo que entregaremos al JComponent para que dibuje la estrella

/* Las siguientes variables sirven para generar el dibujo a partir de la estrella, en ellas
   contemplamos parametros como lo son el angulo actual de la estrella, la posicion actual dentro
   del JComponent, y los puntos de los 2 circulos que usamos para construir el dibujo, todas usadas
   para crear los poligonos LISTOS PARA SER DIBUJADOS
*/
private int posicionActualX,posicionActualY;
private double anguloActual,circuloInteriorX[],circuloInteriorY[],circuloExteriorX[],
               circuloExteriorY[],radioDelCirculoInterior,radioDelCirculoExterior,
               gradosEntreCadaPunto,anguloEntrePuntos,anguloInicial,desplazamiento;
public DibujoDeEstrella(Estrella e){
    miEstrella=e;
    posicionActualX=0;
    posicionActualY=0;
    anguloActual=0.0;
}

private void crearDibujo(){
    calcularCirculos();
    int i;
    dibujos=new LinkedList<Polygon>(); //El centro + cada una de las puntas
    //creamos el centro de una sola vez y lo introducimos dentro de la lista de poligonos a dibujar
    dibujos.add(crearCentro());
    Polygon punta;
    for(i=0;i<circuloExteriorX.length;i++){
        punta=new Polygon();
        punta.addPoint((int)circuloInteriorX[i], (int)circuloInteriorY[i]);
        punta.addPoint((int)circuloExteriorX[i], (int)circuloExteriorY[i]);
        if(i+1<circuloExteriorX.length)
            punta.addPoint((int)circuloInteriorX[i+1], (int)circuloInteriorY[i+1]);
        else
            punta.addPoint((int)circuloInteriorX[0], (int)circuloInteriorY[0]);
        dibujos.add(punta);
    }
}

private Polygon crearCentro(){
    int cx[],cy[],cantidadDePuntos;
    cantidadDePuntos=miEstrella.getCantidadPuntas();
    cx=new int[cantidadDePuntos];
    cy=new int[cantidadDePuntos];
    int i=0;
    for(double x: circuloInteriorX)
        cx[i++]=(int)x;
    i=0;
    for(double y: circuloInteriorY)
        cy[i++]=(int)y;
    return new Polygon(cx,cy,cantidadDePuntos);
}

private void inicializarVariables(){
    //Para nosotros es mas facil y entendible trabajar con grados,
    //sin embargo las funciones de java trabajan con radianes
    gradosEntreCadaPunto=360.0/miEstrella.getCantidadPuntas();

    //para hacer el codigo mas corto y entendible crearemos una variables mas
    //donde esten los angulos que necesitamos en radianes
    anguloEntrePuntos=Math.toRadians(gradosEntreCadaPunto);
    anguloInicial=Math.toRadians(anguloActual);
    desplazamiento=anguloEntrePuntos/2;

    radioDelCirculoExterior=miEstrella.getTamanioPixeles()/2;
    radioDelCirculoInterior=radioDelCirculoExterior*miEstrella.getLargoDePuntas();
}

private void calcularCirculos(){
    circuloInteriorX= new double[miEstrella.getCantidadPuntas()];
    circuloInteriorY= new double[miEstrella.getCantidadPuntas()];
    circuloExteriorX= new double[miEstrella.getCantidadPuntas()];
    circuloExteriorY= new double[miEstrella.getCantidadPuntas()];
    int i;
    double anguloDelPunto;
    for(i=0;i<circuloInteriorX.length;i++){
        anguloDelPunto=anguloInicial+i*anguloEntrePuntos;
        circuloInteriorX[i]=(double)posicionActualX+ radioDelCirculoInterior*Math.cos(anguloDelPunto);
        circuloInteriorY[i]=(double)posicionActualY+ radioDelCirculoInterior*Math.sin(anguloDelPunto);
        circuloExteriorX[i]=(double)posicionActualX+ radioDelCirculoExterior*Math.cos(desplazamiento+anguloDelPunto);
        circuloExteriorY[i]=(double)posicionActualY+ radioDelCirculoExterior*Math.sin(desplazamiento+anguloDelPunto);
    }
}

public LinkedList<Polygon> getDibujos() {
    crearDibujo();
    return dibujos;
}

public void rotar(int grados){
    anguloActual+=(double)grados;
    if(anguloActual>360.0)
        anguloActual-=360.0;
    else if(anguloActual<0.0)
        anguloActual+=360.0;
    anguloInicial=Math.toRadians(anguloActual);
    crearDibujo();
}

public void setCantidadPuntas(int cantidadPuntas) {
    miEstrella.setCantidadPuntas(cantidadPuntas);
    inicializarVariables();
}

public void setColor(Color color) {
    miEstrella.setColor(color);
}

public void setLargoDePuntas(double largoDePuntas) {
    miEstrella.setLargoDePuntas(largoDePuntas);
    inicializarVariables();
}

public Color getColor(){
    return miEstrella.getColor();
}

public void moverArriba(){posicionActualY-=10;}
public void moverAbajo(){posicionActualY+=10;}
public void moverIzquierda(){posicionActualX-=10;}
public void moverDerecha(){posicionActualX+=10;}

public void setTamanio(int t){
    miEstrella.setTamanioPixeles(t);
    inicializarVariables();
}
}

public class Estrella {

public static final int MINIMO_PUNTAS=3,MAXIMO_PUNTAS=10;

private int tamanioPixeles,cantidadPuntas;
private double largoDePuntas;
private Color color;

public Estrella(int tamanioPixeles, int cantidadPuntas, double largoDePuntas, Color color) {
    this.tamanioPixeles = tamanioPixeles;
    this.cantidadPuntas = cantidadPuntas;
    this.largoDePuntas = largoDePuntas;
    this.color = color;
}

public Estrella() {
}

public void setCantidadPuntas(int cantidadPuntas) {
    this.cantidadPuntas = cantidadPuntas;
}

public void setColor(Color color) {
    this.color = color;
}

public void setLargoDePuntas(double largoDePuntas) {
    this.largoDePuntas = largoDePuntas;
}

public void setTamanioPixeles(int tamanioPixeles) {
    this.tamanioPixeles = tamanioPixeles;
}

public int getCantidadPuntas() {
    return cantidadPuntas;
}

public Color getColor() {
    return color;
}

public double getLargoDePuntas() {
    return largoDePuntas;
}

public int getTamanioPixeles() {
    return tamanioPixeles;
}

}

class DoubleJSlider extends JSlider {

final int scale;

public DoubleJSlider(int min, int max, int value, int scale) {
    super(min, max, value);
    this.scale = scale;
}

public double getScaledValue() {
    return ((double)super.getValue()) / this.scale;
}
}  
4

1 に答える 1

3

最初の問題 (色変更イベント) は、カラー チューザーの選択モデルにリスナーを追加したにもかかわらず、カラー チューザーからイベントが発生すると予想されるという事実に関係しています。

public void stateChanged(ChangeEvent e) {

    System.out.println("!! Ping !!" + e.getSource());

    if (e.getSource() == ventana.sliderLargoPuntas) {
        dibujo.setLargoDePuntas(ventana.sliderLargoPuntas.getScaledValue());
    } else if (e.getSource() == ventana.sliderTamanioEstrella) {
        dibujo.setTamanio(ventana.sliderTamanioEstrella.getValue());

    } else if (e.getSource() == ventana.spinnerCantidadPuntas) {
        dibujo.setCantidadPuntas((int) ventana.spinnerCantidadPuntas.getValue());

    // >>--- Change this ------------------------------------------------------------<<
    //} else if (e.getSource() == ventana.ccColor) {
    } else if (e.getSource() == ventana.ccColor.getSelectionModel()) {

        System.out.println("!! Pong !!");
        dibujo.setColor(ventana.ccColor.getColor());
    }
    areaDeTrabajo.pintarEstrella(dibujo);
}

2 番目の問題は、KeyListeners に関するよくある誤解です。KeyListener(まさにあなたが持っている理由から)使用することを強くお勧めしません。代わりにKey Bindingsを使用してください。 KeyListenerアタッチされているコンポーネントがフォーカス可能で、現在フォーカスがある場合にのみ機能します。キーバインディングを使用して、この制限を克服できます。

あなたAreaDeDibujosのクラスでは、 をオーバーライドpaintしましたが、呼び出しに失敗しましたsuper.paint。メソッドは複雑な一連のpaintルーチンであり、非常に正当な理由がない限り、実際には壊したくないものです。

代わりに を使用する必要がありますpaintComponent( を呼び出すことを忘れないでくださいsuper.paintComponent)。他に理由がない場合は、それpaintComponentがダブルバッファリングされていて、そうでpaintはないという事実。

また、これは、使用する必要がないことを意味するg.setColorg.clearRect、スーパー ペイント メソッドが処理してくれるためです。

于 2013-02-07T05:42:22.950 に答える