Cómo hacer JLabel con relleno de imagen BorderLayout.CENTER

Obtuve un JFrame y configuré 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 que la imagen dentro de la etiqueta llenara todo el marco dejando mi menú intacto, por supuesto.

preguntado el 28 de julio de 12 a las 05:07

Espero que la imagen en cuestión sea lo suficientemente grande para ocupar el espacio. Por favor, echa un vistazo a esto ejemplo -

Sí, la imagen es lo suficientemente grande, no es un ícono pequeño ni nada. -

Las etiquetas no cambian el tamaño de los iconos;) -

2 Respuestas

Perdóname si esto parece arrogante, pero no tengo nada más para continuar.

Hice una muestra rápida

Diseño de borde ancho Diseño de borde estrecho

Vea la línea roja alrededor de la imagen, esa es la JLabella frontera. Como puede ver, la etiqueta se ha redimensionado para llenar toda el área.

Este es el código que usé 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, deberá proporcionar su propia imagen;).

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

Si aún tiene problemas, sugeriría (en ausencia de más evidencia) que su etiqueta puede no estar en el contenedor que cree que es o que el administrador de diseño de contenedores no es lo que cree que es.

ACTUALIZACIÓN

No sé por qué tiene problemas con los componentes que faltan o problemas con su menú. ¿Están mezclando componentes pesados ​​y livianos?

Ejemplo con barra de menú

Con barra de menú

Después de leer su pregunta un poco más de cerca, ideé una muestra de panel de imagen de cambio de tamaño simple. Para mayor velocidad, he confiado en mis bibliotecas, pero debería ser razonablemente fácil implementar su propio código en 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

                }

            }

        }

    }

}

Respondido 28 Jul 12, 06:07

Gracias por la muestra. El problema es que se apodera de todo y se pierden otros componentes, como un menú. Tienes razón, mi problema es que la etiqueta no está cambiando el tamaño de la imagen del ícono dentro de ella, lo que es parte del dolor. - MP.

no debería estar afectando sus menús: P - Programador loco

@trashgod sin conocer el nivel de conocimiento del 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 lo básico :P - Programador loco

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

Respondido 28 Jul 12, 09:07

podría decirse que es una implementación ilegal de icon: getIconWidth/Height se documenta para regresar un int especificando el fija ancho del icono - eso no es posible con cambiar el tamaño sobre la marcha ... - kleopatra

En mi humilde opinión, creo que es mejor que con algún tipo de Factory que podría tomar la línea de base Icon y producir un nuevo Icon del tamaño requerido o pinte uno en su nombre. Sin embargo, corre el riesgo de "detener" el EDT si la operación de escalado es considerable (por ejemplo, escalando al 0.1 % o varios al 100 %, según el tamaño de la imagen original). Como muestra mi ejemplo, utiliza un enfoque de "unión" para la solicitud de cambio de tamaño, en lugar de cambiar el tamaño en CADA solicitud, intentamos cambiar el tamaño en la menor cantidad de solicitudes posible, generalmente cuando alcanzamos un estado "inactivo". Pero eso es solo MHO - Programador loco

@madProgrammer lo siento por redactar mal la q original, no quiero cambiar el tamaño de la imagen dentro del icono. Solo quiero que la imagen se estire para llenar el componente principal. Sé que esta mala redacción probablemente arruinó tu respuesta, pero espero que aborde por qué intenté lo que hice. - MP.

@mP está bien, entonces, ¿el estiramiento no cambia el tamaño? ¿Es que Evan no te importa mantener la relación de aspecto? Programador loco

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.