#java #swing #size #jbutton #paintcomponent
#java #swing #размер #jbutton #paintcomponent
Вопрос:
Я пытаюсь исправить JFrame, где будет фоновое изображение и на изображении JButtons, которые будут выполнять некоторые команды. Я пытаюсь сделать это без макета, потому что я хочу разместить маленькие кнопки в определенных местах JFrame, но каждый раз, когда я это делаю, фоновое изображение выходит на передний план или JFrame имеет размер, равный размеру JFrame. С помощью следующего кода JButton имеет тот же размер, что и JFrame. Я пытался изменить размер и расположение JButton, но ничего не вышло. Не могли бы вы мне помочь, пожалуйста?
вот код
public final class Test extends JComponent
{
private Image background;
private JFrame frame;
private Dimension dimension;
public Test()
{
dimension = new Dimension(15, 15);
frame = new JFrame("Iphone");
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(this);
frame.setBounds(641, 0, 344, 655);
frame.setVisible(true);
test = displayButton("tigka");
frame.getContentPane().add(test);
}
public void update(Graphics g)
{
paint(g);
}
public void paintComponent(Graphics g)
{
super.paintComponents(g);
g.drawImage(background, 0, 25, null); // draw background
// label();
test = displayButton("test");
}
public JButton displayButton(String name)
{
JButton button = new JButton(name);
button.setSize(100, 100);
button.setPreferredSize(dimension);
return button;
}
Комментарии:
1. избавьтесь от метода update(). Нет необходимости переопределять этот метод в Swing. Это старый код для AWT и его не следует использовать в приложении Swing.
Ответ №1:
Вам нужно изменить content pane
, чтобы получить фон для вашего Frame
.
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("Test");
frame.setContentPane(new JPanel() {
BufferedImage image = ImageIO.read(new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, 300, 300, this);
}
});
frame.add(new JButton("Test Button"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
}
Вывод:
Комментарии:
1. неправильно: (может быть опечатка) вызываемый суперметод — это paintComponent вместо paintComponent s
2. а теперь снова измените порядок вызовов 😉
3. @dacwe @kleopatra если вы измените его на paintComponent (что, я думаю, правильно), то его следует использовать в качестве первого для выполнения всей закрашивания по умолчанию, поверх которого вы затем хотите нарисовать свое изображение. Протестируйте это сами.
4. @Boro, это то, что я имел в виду — смотрите Мой комментарий к ответу Томаса — было слишком лениво повторять это здесь 🙂
5. @kleopatra да. Я видел это, но позже. Я его тоже дополнил. Извините за повторение. Кстати 1 @dacwe очень хороший ответ и отличный пример.
Ответ №2:
Вы пробовали использовать JLabel с HTML в метке? Что-то вроде этого:
import javax.swing.*;
public class SwingImage1
{
public static void main( String args[] )
{
JFrame frm = new JFrame( "Swing Image 1" );
JLabel lbl = new JLabel( "<html><body><img src="http://liv.liviutudor.com/images/liv.gif"></body></html>" );
frm.getContentPane().add( lbl );
frm.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frm.pack();
frm.setVisible( true );
}
}
затем поверх вашей метки вы можете добавить свою кнопку?
Комментарии:
1. На самом деле это другой метод решения этой проблемы. Это поможет мне решить проблему, с которой я сталкиваюсь сейчас, но я думаю, что это также изменит многие мысли позже. Спасибо вам за ваш ответ, хотя
2. -1 для использования html там, где это не требуется … создайте и установите вместо этого ImageIcon. Плюс с помощью надписи вообще не очень хорошая идея: требование-иметь почву под обычные компоненты, которые добавляются …
Ответ №3:
Вы должны поменять местами эти две строки:
super.paintComponents(g); //paints the children, like the button
g.drawImage(background, 0, 25, null); // draw background later possibly overwriting the button
Таким образом, порядок должен быть таким:
g.drawImage(background, 0, 25, null);
super.paintComponents(g);
Кроме того, обратите внимание, что макет панели содержимого по умолчанию — BorderLayout . Таким образом, вы бы явно установили для макета вашей панели содержимого значение null.
Комментарии:
1. Это был очень полезный ответ, потому что я не знал о макете панели содержимого по умолчанию. Спасибо. Что касается первого совета, в чем разница?
2. В моем посте нет никакой разницы, только ваш код с комментариями и подсказкой поменять их местами. 🙂
3. никогда не прикасайтесь к методам рисования awt в Swing JComponents 😉 Так что это значение равно -1, за исключением того, что оно было полезным в том смысле, что меня это полностью озадачило — потому что вызов super.paintComponent перед пользовательским кодом рисования является последовательностью для реализации (в противном случае пользовательская краска была бы закрашена фоном для непрозрачных компонентов)
4. Да, это была бы правильная последовательность, но он вызвал
super.paintComponents
неsuper.paintComponent
. Кроме того, вы правы, что не вызываете этот метод вручную, а скорее вызываетеpaintComponent
(не распознал это как потенциальную опечатку :)).
Ответ №4:
/*it is simple to put button on image first set image by making object then make button object amp; add the button object direct to image object rather then add to frame.*/
package frame;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class frame
{
public frame()
{
JFrame obj = new JFrame("Banking Software");
JButton b1 = new JButton("Opening Account");
JLabel image = new JLabel(new ImageIcon("money.jpg"));
image.setBounds(0,0, 1600, 1400);
obj.setExtendedState(JFrame.MAXIMIZED_BOTH);
obj.add(image);
b1.setBounds(500,400, 100, 40);
image.add(b1);
obj.setVisible(true);
}
public static void main(String args[])
{
new frame();
}
}