Java Swing - Ширина JLabel изменилась при добавлении иконки или текста? - PullRequest
2 голосов
/ 25 июля 2011

Тот же вопрос, другой контекст

Кажется, я был слишком поспешен в принятии ранее, так как проблема все еще существует. Эта проблема? JLabel может свободно расширять родительскую панель при добавлении в нее контента.

Пришло время воспроизвести его согласно предложению "Судно на воздушной подушке с угрями", и вот оно:

import java.awt.*;
import javax.swing.*;

public class TestLabel {    
    public static void main(String[] args) {
    // Var inits
        JFrame frame;
    JPanel panel;
    JLabel label;
    Container pane;
    GridBagConstraints gbc = new GridBagConstraints();

    // Frame, content pane, layout inits
    frame = new JFrame("Label Tester");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        

        pane = frame.getContentPane();   
        pane.setLayout(new GridBagLayout());

        gbc.weighty = 1;
        gbc.fill = GridBagConstraints.BOTH;


        // Add panels (note gbc weighty and fill carries over all instances)
        gbc.weightx = 0.3;
        gbc.gridx = 0;
        gbc.gridy = 0;
        panel = new JPanel();
        panel.setBackground(Color.GREEN);
        frame.add(panel,gbc);

        label = new JLabel("THE PANEL IS NOW DISTORTED TO FIT THIS LABEL WHY IS THIS HAPPENING");
        //label = new JLabel("");
        label.setOpaque(true);
        label.setBackground(Color.WHITE);   
        panel.add(label);

        gbc.weightx = 0.7;
        gbc.gridx = 1;
        gbc.gridy = 0;
        panel = new JPanel();
        panel.setBackground(Color.RED);
        frame.add(panel,gbc);

        gbc.weightx = 0.3;
        gbc.gridx = 0;
        gbc.gridy = 1;
        panel = new JPanel();
        panel.setBackground(Color.BLUE);
        frame.add(panel,gbc);

        gbc.weightx = 0.7;
        gbc.gridx = 1;
        gbc.gridy = 1;
        panel = new JPanel();
        panel.setBackground(Color.YELLOW);
        frame.add(panel,gbc);

        frame.pack();
        frame.setSize(800,600);  

        frame.setVisible(true);  
    }
}

Результаты:

enter image description here

Как видите, зеленая панель становится шире и отбрасывает весь макет, когда к нему добавляется текст (или, в исходном вопросе, и значок). Я хочу, чтобы мой макет оставался одинаковым по весу независимо от содержимого. Причина, по которой это возникло, заключается в том, что я пытаюсь добавить масштабированное изображение в виде значка на ярлык, как видно из исходного вопроса.

Кстати, setPreferredSize(), похоже, не работает.

Есть ли способ это исправить?


Оригинальный вопрос

Мой элемент JLabel значительно расширяется, когда я добавляю в него иконку. Почему это происходит? Вот соответствующая часть кода:

// Show label and BG color
redLabel.setBackground(Color.RED);
redLabel.setOpaque(true);

// Grab stretched image (already loaded elsewhere in the code) and turn to icon
Img = Img.getScaledInstance(redLabel.getWidth(),12,Image.SCALE_REPLICATE);
ImageIcon icon = new ImageIcon(Img); 

// This line throws everything off! 
//It's commented out in the first pic, and included in the second.
redLabel.setIcon(icon);

Как вы можете видеть из первого рисунка, у меня есть метка (красного цвета) шириной W. Я пытаюсь растянуть иконку до ширины W и поместить ее в метку.

Когда я это делаю, метка расширяется (я думаю, ровно на 50 пикселей), а также сжимается по левому краю (зеленый). Кто-нибудь знает, почему это происходит?

Я пробовал несколько вещей, которые слишком многословны, чтобы объяснить, но не могу найти проблему: - /

enter image description here

Ответы [ 3 ]

3 голосов
/ 25 июля 2011

Ваш компонент расширяется, поскольку он выделяет необходимое пространство для его Icon.


public class JLabelDemo {
    private static BufferedImage bi;

    public static void main(String[] args) throws IOException{
        loadImage();

        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                createAndShowGUI();             
            }
        });
    }

    private static void loadImage() throws IOException{
        bi = ImageIO.read(JLabelDemo.class.getResource("../resource/forever-alone.jpg"));
    }

    private static void createAndShowGUI(){
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JPanel panel = new JPanel();
        panel.setBackground(Color.YELLOW);
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        final JLabel emptyLabel = new JLabel();
        final JLabel textLabel = new JLabel("This label has text only");
        final JLabel textAndImageLabel = new JLabel("This label has text and image");
        textAndImageLabel.setIcon(new ImageIcon(bi));

        panel.add(emptyLabel);
        panel.add(textLabel);
        panel.add(textAndImageLabel);
        frame.add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        System.out.println("Empty label dimensions - " + emptyLabel.getSize());
        System.out.println("Text only label dimensions - " + textLabel.getSize());
        System.out.println("Image width: " + bi.getWidth() + ", Image height: " + bi.getHeight());
        System.out.println("Text and image label dimensions - " +textAndImageLabel.getSize());
    }
}

enter image description here


На консоль выводится следующее:

Empty label dimensions - java.awt.Dimension[width=0,height=0]
Text only label dimensions - java.awt.Dimension[width=129,height=16]
Image width: 194, Image height: 180
Text and image label dimensions - java.awt.Dimension[width=363,height=180]
2 голосов
/ 26 июля 2011

Рассмотрите возможность использования JLayeredPane для добавления компонентов в слои. Тем не менее, при отключении, размере и расположении добавляемых компонентов возникают ошибки и ловушки.

Например,

import java.awt.*;
import javax.swing.*;

public class TestLabel {
   private static final Dimension SIZE = new Dimension(800, 600);

   public static void main(String[] args) {
      GridBagConstraints gbc = new GridBagConstraints();


      JPanel defaultPane = new JPanel();
      defaultPane.setLayout(new GridBagLayout());

      gbc.weighty = 1;
      gbc.fill = GridBagConstraints.BOTH;

      // Add panels (note gbc weighty and fill carries over all instances)
      gbc.weightx = 0.3;
      gbc.gridx = 0;
      gbc.gridy = 0;
      JPanel panel = new JPanel();
      panel.setBackground(Color.GREEN);
      defaultPane.add(panel, gbc);

      gbc.weightx = 0.7;
      gbc.gridx = 1;
      gbc.gridy = 0;
      panel = new JPanel();
      panel.setBackground(Color.RED);
      defaultPane.add(panel, gbc);

      gbc.weightx = 0.3;
      gbc.gridx = 0;
      gbc.gridy = 1;
      panel = new JPanel();
      panel.setBackground(Color.BLUE);
      defaultPane.add(panel, gbc);

      gbc.weightx = 0.7;
      gbc.gridx = 1;
      gbc.gridy = 1;
      panel = new JPanel();
      panel.setBackground(Color.YELLOW);
      defaultPane.add(panel, gbc);
      defaultPane.setSize(SIZE);

      JLabel label = new JLabel("THE PANEL IS NOW DISTORTED TO FIT THIS LABEL WHY IS THIS HAPPENING");
      label.setOpaque(true);
      label.setBackground(Color.WHITE);

      JPanel northPalettePanel = new JPanel();
      northPalettePanel.setOpaque(false);
      northPalettePanel.add(label);

      JPanel palettePanel = new JPanel(new BorderLayout());
      palettePanel.setOpaque(false);
      palettePanel.setSize(SIZE);
      palettePanel.setLocation(0, 0);
      palettePanel.add(northPalettePanel, BorderLayout.NORTH);

      JLayeredPane layeredPane = new JLayeredPane();
      layeredPane.setPreferredSize(SIZE);
      layeredPane.add(defaultPane, JLayeredPane.DEFAULT_LAYER);
      layeredPane.add(palettePanel, JLayeredPane.PALETTE_LAYER);

      JFrame frame = new JFrame("Label Tester");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(layeredPane, BorderLayout.CENTER);
      frame.pack();

      frame.setVisible(true);
   }
}
1 голос
/ 25 июля 2011

Java Swing довольно старый для меня, но, если я хорошо помню, установка предпочтительного размера (setPreferredSize ()) иногда решает подобные проблемы ... Также попробуйте верхнее наложение с setMaximumSize и setMinimumSize.

Вы можете найти больше информации в документации по Java: http://download.oracle.com/javase/tutorial/uiswing/layout/using.html#sizealignment

Привет!

...