2011-09-28 12 views
5

ecco una SSCCE:swing BoxLayout problema con JComboBox senza utilizzare setXXXSize

import java.awt.Color; 
import java.awt.Dimension; 
import javax.swing.Box; 
import javax.swing.BoxLayout; 
import javax.swing.JButton; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 


public class BoxLayoutTest extends JFrame { 

    public BoxLayoutTest(){ 
     JPanel main = new JPanel(); 
     main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS)); 
     main.setBackground(Color.red); 
     this.add(main); 
     JPanel northPanel = new JPanel(); 

     JPanel middle = new JPanel(); 
     middle.setLayout(new BoxLayout(middle, BoxLayout.X_AXIS)); 
     middle.add(new JButton("FOO")); 
     middle.add(Box.createHorizontalGlue()); 

     JPanel aPanel = new JPanel(); 
     aPanel.setBackground(Color.black); 

      JComboBox b = new JComboBox(); 
    //b.setPreferredSize(new Dimension(100,16)); //uncomment this to see the layout I would like to achieve 
    //b.setMaximumSize(new Dimension(100,16)); 
     //middle.add(b); //uncomment this line 

     middle.setBackground(Color.green); 
     northPanel.setBackground(Color.blue); 

     main.add(northPanel); 
     main.add(middle); 
     main.add(Box.createVerticalGlue()); 

     this.setSize(800,600); 
     this.setResizable(true); 
     this.setVisible(true); 
    } 

    public static void main(String[] args) { 
     new BoxLayoutTest(); 
    } 

} 

Sto cercando di refactoring alcune classi che ho scritto qualche tempo fa, quando non sapevo che l'utilizzo di metodi setXXXSize su componenti è sbagliata . Utilizzando una cornice ridimensionabile, il risultato che voglio ottenere è la seguente:

  1. Il northPanel dovrebbe rimanere in cima e cambiare la sua dimensione di conseguenza per le modifiche di dimensioni telaio (sembra funzionare bene)
  2. Il pannello verde dove ho messo il JButton dovrebbe mantenere la dimensione massima del JButton e stare appena sotto il pannello blu sopra (questo funziona bene se metto solo JButtons all'interno di quel pannello).

Il problema si pone se inserisco un JComboBox all'interno del pannello verde (prova a decommentare la riga in SSCCE). Immagino che JComboBox non abbia una dimensione massima specificata, quindi si estende con la cornice. Nella precedente versione errata del mio codice stavo usando i metodi setxxxSize su JComboBox per limitare la sua dimensione (prova a decommentare la linea sui metodi setXXXSize per vederla).

La mia domanda è:

  1. E 'possibile ottenere lo stesso risultato utilizzando BoxLayout senza invocare metodi setXXXSize()?
  2. Se sì, come?
  3. c'è qualche altro LayoutManager che posso usare per ottenere in tal senso?

Prego mi ha messo nella giusta direzione

risposta

9

JComboBox si comporta male (lo stesso che JTextField) in segnalato un altezza massima illimitata: non dovrebbe mai mostrare più di una sola riga. Rimedio è lo stesso: sottoclasse e tornare ad un'altezza ragionevole

 JComboBox b = new JComboBox() { 

      /** 
      * @inherited <p> 
      */ 
      @Override 
      public Dimension getMaximumSize() { 
       Dimension max = super.getMaximumSize(); 
       max.height = getPreferredSize().height; 
       return max; 
      } 

     }; 

solo per divertimento, ecco un frammento utilizzando MigLayout (che è il mio preferito personali al momento :-)

// two panels as placeholders 
    JPanel northPanel = new JPanel(); 
    northPanel.setBackground(Color.YELLOW); 
    JPanel southPanel = new JPanel(); 
    southPanel.setBackground(Color.YELLOW); 
    // layout with two content columns 
    LC layoutContraints = new LC().wrapAfter(2) 
      .debug(1000); 
    AC columnContraints = new AC() 
    // first column pref, followed by greedy gap 
      .size("pref").gap("push") 
      // second 
      .size("pref"); 
    // three rows, top/bottom growing, middle pref 
    AC rowContraints = new AC() 
     .grow().gap().size("pref").gap().grow(); 
    MigLayout layout = new MigLayout(layoutContraints, columnContraints, 
      rowContraints); 
    JPanel main = new JPanel(layout); 
    main.setBackground(Color.WHITE); 
    // add top spanning columns and growing 
    main.add(northPanel, "spanx, grow"); 
    main.add(new JButton("FOO")); 

    // well-behaved combo: max height == pref height 
    JComboBox combo = new JComboBox() { 

     @Override 
     public Dimension getMaximumSize() { 
      Dimension max = super.getMaximumSize(); 
      max.height = getPreferredSize().height; 
      return max; 
     } 

    }; 
    // set a prototype to keep it from constantly adjusting 
    combo.setPrototypeDisplayValue("somethingaslongasIwant"); 

    main.add(combo); 
    // add top spanning columns and growing 
    main.add(southPanel, "spanx, grow"); 
+0

grazie per la risposta. Sembra che sia un errore di Swing, verrà risolto? – Heisenbug

+0

@Heisenbug - non lo so, chiedi al team Swing :-) – kleopatra

3

ho sempre visto con il i gestori di layout nel jdk non sono facili. Sono troppo semplici e inflessibili o il gridbaglayoutout è troppo disturbo. Invece ho iniziato a usare il layout della scheda jgoodies e non ho mai guardato indietro da allora ... Date un'occhiata. È molto semplice e facile da usare. Ecco un link:

http://www.jgoodies.com/freeware/forms/

Assicurarsi che si passa attraverso la carta bianca.

E ora, abbiamo anche Google ci fornisce un editor per la WYSISWG FormLayout come un plugin per Eclipse. Questo rende la vita molto più semplice.

http://code.google.com/javadevtools/wbpro/palettes/swing_palette.html