Изменить размер кнопки

Я пытаюсь изменить размер кнопки в моем JFrame. Каждый ответ, который я вижу на этот вопрос, говорит об использовании button.setPreferredSize(new Dimension(x, y)) или button.setSize(new Dimension(x, y)), но ни один из них не работает. Название кнопки отображается в нужном месте, но сама кнопка занимает весь экран. Я также попытался добавить кнопку в рамку вместо панели. Когда я это делаю, кнопка имеет правильный размер, но находится за пределами изображения. Как расположить и изменить размер этой кнопки, чтобы она отображалась поверх изображения?

public ImageTest(String title, String imageSource, int minimum, int middle, int maximum, int curr, boolean x) { // Extends JFrame...
        frame = new JFrame();
        frame.setTitle(title);
        frame.setLayout(new GridBagLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        maxim = maximum;
        minim = minimum;
        mercSize(minim, maxim, curr); //change size of mercury in thermometer

        pane = new PaintPane(new ImageIcon(imageSource).getImage());
        pane.setLayout(new BorderLayout());
        frame.add(pane);

        b1 = new JButton("Increase Temp");
        b1.setPreferredSize(new Dimension(100, 100)); //Button does not work yet
        b1.setBorder(BorderFactory.createEmptyBorder(560,250,0,0));
        b1.setLocation(95, 45);
        pane.add(b1);
        frame.pack();

        min = new JLabel("" + minimum);
        min.setFont(min.getFont().deriveFont(Font.BOLD, 28));
        if(x == true) min.setForeground(Color.BLACK); //Changes the font color to match the image
        else min.setForeground(Color.WHITE);
        min.setVerticalAlignment(JLabel.TOP);
        min.setVerticalTextPosition(JLabel.TOP);
        min.setBorder(BorderFactory.createEmptyBorder(445, 150, 0, 0)); //Positions the text
        pane.add(min);
        frame.pack();

        mid = new JLabel("" + middle);
        mid.setFont(mid.getFont().deriveFont(Font.BOLD, 28));
        if(x == true) mid.setForeground(Color.BLACK); //Changes the font color to match the image
        else mid.setForeground(Color.WHITE);
        mid.setVerticalAlignment(JLabel.TOP);
        mid.setVerticalTextPosition(JLabel.TOP);
        mid.setBorder(BorderFactory.createEmptyBorder(240, 150, 0, 0)); //Positions the text
        pane.add(mid);
        frame.pack();

        max = new JLabel("" + maximum);
        max.setFont(max.getFont().deriveFont(Font.BOLD, 28));
        if(x == true) max.setForeground(Color.BLACK); //Changes the font color to match the image
        else max.setForeground(Color.WHITE);
        max.setVerticalAlignment(JLabel.TOP);
        max.setVerticalTextPosition(JLabel.TOP);
        max.setBorder(BorderFactory.createEmptyBorder(35, 150, 0, 0)); //Positions the text
        pane.add(max);
        frame.pack();

        temp = new JLabel("Current Temperature: " + curr);
        temp.setFont(temp.getFont().deriveFont(Font.BOLD, 28));
        if(x == true) temp.setForeground(Color.BLACK); //Changes the font color to match the image
        else temp.setForeground(Color.WHITE);
        temp.setVerticalAlignment(JLabel.TOP);
        temp.setVerticalTextPosition(JLabel.TOP);
        temp.setBorder(BorderFactory.createEmptyBorder(560, 120, 0, 0)); //Positions the text
        pane.add(temp);
        frame.pack();

        error = new JLabel();

        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

person Radi0actvChickn    schedule 14.10.2013    source источник
comment
JLabel, JButton.... имеет (реализовано в API) горизонтальное и вертикальное выравнивание   -  person mKorbel    schedule 14.10.2013


Ответы (1)


У вас есть ряд сложных вопросов. По сути, вы устанавливаете менеджер компоновки PaintPane на BorderLayout, а затем пытаетесь добавить в него кучу компонентов.

BorderLayout будет принимать решения о том, как лучше, по его мнению, должен быть размещен контент, основываясь на ряде факторов (предпочтительный размер компонента CENTER и минимальный размер для внешних компонентов... если я правильно помню...)

Давайте посмотрим поближе...

public ImageTest(String title, String imageSource, int minimum, int middle, int maximum, int curr, boolean x) { // Extends JFrame...
    //...
    pane = new PaintPane(new ImageIcon(imageSource).getImage());
    pane.setLayout(new BorderLayout());
    // Add button to center position
    pane.add(b1);
    // Add min to center position, overwriting b1
    pane.add(min);
    // Add mid to center position, overwriting 
    pane.add(mid);
    // Add max to center position, overwriting mid
    pane.add(max);
    // Add temp to center position, overwriting max
    pane.add(temp);
    frame.pack();
    //...
}

Каждый раз, когда вы добавляете новый компонент в PaintPane, вы, по сути, удаляете то, что когда-либо было там раньше (он все еще находится в контейнере, просто не будет отображаться). Это связано с тем, что BorderLayout позволяет отображать только один компонент в каждом из 5 мест макета. Позиция по умолчанию всегда CENTER

Это означает, что temp является последним добавленным компонентом, фрейм будет использовать его предпочтительный размер в качестве основы для расчета размера фрейма (плюс любые другие компоненты, которые могут отображаться на фрейме).

Лучшим решением может быть использование другого менеджера компоновки...

Вы также должны взглянуть на Должен ли я избегать использование методов set(Preferred|Maximum|Minimum)Size в Java Swing?

person MadProgrammer    schedule 14.10.2013
comment
Когда я убираю код JButton, все остальное появляется в нужных местах, и все в порядке. Кажется, что frame.pack() после каждого pane.add() позаботился об этом. Я попробую другой менеджер компоновки, хотя - person Radi0actvChickn; 14.10.2013
comment
Это, казалось, не делало ничего другого - person Radi0actvChickn; 14.10.2013
comment
Что-то странное в вашем расположении макета, у вас должен быть только один компонент на экране, наложенный поверх вашего panel - person MadProgrammer; 14.10.2013
comment
Я только начал работать с JPanel, JFrame, JLabel и т. д. около 24 часов назад, поэтому я просто смешивал вещи, пока они не заработали. - person Radi0actvChickn; 14.10.2013
comment
Я только что смешивал вещи вместе Добавьте котел и несколько заклинаний, и у вас есть «магия». К сожалению, магия и программирование несовместимы. Используйте учебники, а не кучу бессмысленных вопросов о том, как изменить размер (мы не должны их угадывать) элементов графического интерфейса. - person Andrew Thompson; 14.10.2013
comment
Спасибо, что восприняли это так буквально и за полезный комментарий..... Я опубликовал это, чтобы посмотреть, было ли перепутано всего несколько строк, но, похоже, это немного больше. Так что да, я читаю учебники. - person Radi0actvChickn; 14.10.2013