2012-07-28 12 views
5

Tengo un JFrame y configuro el LayoutManager en BorderLayout y luego procedí a agregar mi JLabel con una imagen. Sin embargo, cuando cambio el tamaño del marco, JLabel no cambia de tamaño. No he agregado ningún componente a Norte, S, E, etc. Esperaba simplemente tener la imagen dentro de la etiqueta llenando todo el cuadro dejando mi menú intacto, por supuesto.Cómo hacer JLabel con relleno de imagen BorderLayout.CENTER

+0

Espero que la imagen en cuestión sea lo suficientemente grande como para ocupar el espacio. Por favor, eche un vistazo a este [ejemplo] (http://stackoverflow.com/a/11372350/1057230) –

+0

Sí, la imagen es bastante grande, no es un ícono ni nada. –

+0

¿Tiene algún código de muestra? – MadProgrammer

Respuesta

8

Perdóneme si esto parece arrogante, pero no tengo nada más que seguir.

lo hice una muestra rápida

BorderLayout wide BorderLayout narrow

Ver la línea roja alrededor de la imagen, que es la frontera JLabel 's. Como puede ver, la etiqueta se ha vuelto a clasificar según el tamaño para llenar el área entera.

Este es el código que utiliza para producir la muestra

public class LayoutFrame extends JFrame { 

    public LayoutFrame() throws HeadlessException { 

     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     Image image = null; 
     URL url = getClass().getResource("/layout/issue78.jpg"); 
     try { 
      image = ImageIO.read(url); 
     } catch (IOException ex) { 

      ex.printStackTrace(); 

     } 

     JLabel label = new JLabel(new ImageIcon(image)); 
     label.setHorizontalAlignment(JLabel.CENTER); 
     label.setVerticalAlignment(JLabel.CENTER); 
     label.setBorder(new LineBorder(Color.RED, 4)); 

     setLayout(new BorderLayout()); 

     add(label); 

    } 

    public static void main(String[] args) { 

     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 

       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       LayoutFrame frame = new LayoutFrame(); 
       frame.setSize(200, 200); 
       frame.setLocationByPlatform(true); 
       frame.setVisible(true); 

      } 
     }); 

    } 

} 

Obviamente, tendrá que proporcionar su propia imagen;).

No olvide que la etiqueta NO escalará el contenido para usted, si ese es su objetivo, tendrá que implementar su propio componente para lograrlo.

Si aún tiene problemas, le sugiero (a falta de más pruebas) que su etiqueta puede no estar en el contenedor que cree que es o que el administrador de disposición de contenedores no es lo que cree que es.

ACTUALIZACIÓN

No sé por qué usted está teniendo problemas con los componentes que va cuestiones que faltan o con usted menú. ¿Están mezclando componentes pesados ​​y livianos?

muestra con barra de menú

With menu bar

Después de leer su pregunta un poco más cerca, he ideado una sencilla muestra de panel de imagen cambio de tamaño. Para la velocidad, yo he confiado en mis bibliotecas, pero debe ser razonablemente fácil aplicación a su propio código en el lugar de mis llamadas

public class ImagePane extends JPanel { 

    protected static final Object RESIZE_LOCK = new Object(); 

    private BufferedImage image; 
    private BufferedImage scaledImage; 
    private Timer resizeTimer; 

    public ImagePane() { 

     URL url = getClass().getResource("/layout/issue78.jpg"); 
     try { 
      image = ImageIO.read(url); 
     } catch (IOException ex) { 

      ex.printStackTrace(); 

     } 

     resizeTimer = new Timer(250, new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 

       // Simple thread factory to start a slightly lower 
       // priority thread. 
       CoreThreadFactory.getUIInstance().execute(new ResizeTask()); 

      } 

     }); 

     resizeTimer.setCoalesce(true); 
     resizeTimer.setRepeats(false); 

    } 

    @Override 
    public void setBounds(int x, int y, int width, int height) { 

     super.setBounds(x, y, width, height); 

     resizeTimer.restart(); 

    } 

    @Override 
    protected void paintComponent(Graphics g) { 

     super.paintComponent(g); 

     Graphics2D g2d = (Graphics2D) g; 
     if (scaledImage != null) { 

      // This simply returns a rectangle that takes into consideration 
      //the containers insets 
      Rectangle safeBounds = UIUtilities.getSafeBounds(this); 

      System.out.println("scaledImage = " + scaledImage.getWidth() + "x" + scaledImage.getWidth()); 

      int x = ((safeBounds.width - scaledImage.getWidth())/2) + safeBounds.x; 
      int y = ((safeBounds.height - scaledImage.getHeight())/2) + safeBounds.y; 

      g2d.drawImage(scaledImage, x, y, this); 

     } 

    } 

    protected class ResizeTask implements Runnable { 

     @Override 
     public void run() { 

      synchronized (RESIZE_LOCK) { 

       if (image != null) { 

        int width = getWidth(); 
        int height = getHeight(); 

        System.out.println("width = " + width); 
        System.out.println("height = " + height); 

        // A simple divide and conquer resize implementation 
        // this will scale the image so that it will fit within 
        // the supplied bounds 
        scaledImage = ImageUtilities.getScaledInstanceToFit(image, new Dimension(width, height), ImageUtilities.RenderQuality.High); 

        System.out.println("scaledImage = " + scaledImage.getWidth() + "x" + scaledImage.getWidth()); 

        repaint(); // this is one of the few thread safe calls 

       } 

      } 

     } 

    } 

} 
+0

gracias por la muestra. El problema es que se apodera de todo y otros componentes se pierden, como un menú. Tienes razón, mi problema es que la etiqueta no está redimensionando la imagen del icono dentro de la parte del dolor. –

+0

no debería afectar sus menús: P – MadProgrammer

+0

@trashgod sin saber el nivel de conocimiento de la OP, no quería sonar condescendiente, pero no tenía idea de lo que se había intentado, así que no tuve más remedio que comenzar por conceptos básicos: P – MadProgrammer

1

mejor opción es ImageIcon subclase y anular su método paintIcon simplemente pintar la imagen usando Graphics.paint (x, y, ancho, alto ...).

+1

podría decirse que es una implementación ilegal del ícono: getIconWidth/Height se doc'ed para devolver _un int especificando el ancho ** fijo ** del ícono_ - eso no es posible con el cambio de tamaño sobre la marcha ... – kleopatra

+0

en mi humilde opinión Creo que Mejor con algún tipo de 'Fábrica' que podría tomar el' Icono' de la línea base y producir un nuevo 'Icono' del tamaño requerido o pintar uno en su nombre. Sin embargo, usted corre el riesgo de "detener" el 'EDT' si la operación de escalado es considerable (por ejemplo, reduciendo a 0.1% o más de 100%, dependiendo del tamaño de la imagen original). Como muestra mi ejemplo, utiliza un enfoque de "fusión" para la solicitud de cambio de tamaño, en lugar de cambiar el tamaño de CADA petición, intentamos cambiar el tamaño de la menor cantidad posible de solicitudes, generalmente cuando alcanzamos un estado "inactivo". Pero eso es solo MHO – MadProgrammer

+0

@madProgrammer disculpa por haber escrito mal el original q, no quiero cambiar el tamaño de la imagen dentro del ícono. Solo quiero que la imagen se alargue para llenar el componente principal. Sé que esta mala redacción probablemente arruinó tu respuesta, pero espero que explique por qué probé lo que hice. –