【问题标题】:JButtons in JPanel don't display properly until repainted through resize or action在通过调整大小或操作重新绘制之前,JPanel 中的 JButton 无法正确显示
【发布时间】:2012-05-31 14:36:49
【问题描述】:

这个问题我已经有一段时间了,搜索了很多论坛和网站(包括这个),但仍然没有找到我的问题的答案。

这是我的问题: 我正在建立一个视觉日历。我有一个包含多个面板的父面板。我重新绘制父面板,并使 3 覆盖不透明(假)。 在我调整框架大小之前不会显示父面板的绘制(或使用覆盖 3 个按钮之一的按钮,但在此示例中省略了这些按钮,因为它会使代码更长) p>

不管怎样,这里是代码,我把它简化为问题部分:

public class Calendar extends JPanel{

  public static void main(String[] args){
    JFrame frame = new JFrame();
    frame.setSize(1600,150);
    frame.add(new Calendar());
    frame.setVisible(true);
  }

  public Calendar(){
    setLayout(new GridBagLayout());
    GridBagConstraints cc = new GridBagConstraints();
    cc.weightx = 1;
    cc.weighty = 1;
    cc.gridx = 0;
    cc.fill = GridBagConstraints.BOTH;

    //Initiate Panels
    JPanel yearpanel = new JPanel();
    JPanel monthpanel = new JPanel();
    JPanel daypanel = new JPanel();

    yearpanel.setLayout(new GridBagLayout());
    monthpanel.setLayout(new GridBagLayout());
    daypanel.setLayout(new GridBagLayout());

    // Set sizes
    int width = (int) this.getPreferredSize().getWidth();
    int height = (int) (this.getPreferredSize().getHeight() / 3);
    yearpanel.setSize(width,height);
    daypanel.setSize(width,height);
    monthpanel.setSize(width,height);

    //make transparent
    yearpanel.setOpaque(false);
    monthpanel.setOpaque(false);
    daypanel.setOpaque(false);
  }        

  @Override
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Image image = Toolkit.getDefaultToolkit().getImage("Images/CalendarBackground.jpg");
    g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), null);
  }
}

我不知道为什么会这样 + 我在网上找不到答案,只有遇到相同问题的人的问题被放弃了:/

谁能帮帮我?

【问题讨论】:

  • 您想修改您的SSCCE - 目前它不起作用。您正在创建空的JPanels,它们永远不会添加到顶级JPanel - 即Calendar

标签: java resize jpanel paint paintcomponent


【解决方案1】:
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    Image image = Toolkit.getDefaultToolkit().getImage("Images/CalendarBackground.jpg");
    g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), null);
}
  1. 不应在绘制方法中加载image。相反,它应该被声明为类属性并预加载。
  2. Toolkit 方法是异步的,因此将组件用作ImageObserver 更为重要。

    g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), this);


这是一个working SSCCE,就像您正在尝试的那样。

【讨论】:

  • 我正要写同样的建议。此外,您可以使用 ImageIO.read(new File(...)),而不是使用 Toolkit。这将返回一个可以立即使用的 BufferedImage。您绝对不应该在绘图调用中加载图像。
  • @Tony 微笑服务。 :)
  • @Tony "你可以使用 ImageIO.read.." 这正是链接代码的作用。但为了安全起见,ImagePanel 将自己声明为ImageObserver。即使使用异步加载的图像,这也可以完成工作。例如,当使用 ImageIcon 加载 动画 GIF(作为 BG 有点令人不安)时,这会有所帮助。
  • 现在可以使用了!谢谢大家,我自己从来没有想过这个。 :)
  • 很高兴你把它整理好了。 :) 有机会请accept 回答。另请参阅Show an animated BG in Swing。 ;)
【解决方案2】:

检查Graphics.drawImage() 的返回值。我敢打赌它会返回 false,这意味着您正在绘制的图像尚未完全加载和缩放。尝试将图像加载到您的 paintComponent 方法以外的其他位置,例如您的 Calendar 构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-21
    • 2012-06-21
    • 2012-11-03
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-09
    • 2019-04-17
    相关资源
    最近更新 更多