Java 不显示滚动条

Java 不显示滚动条,java,swing,jframe,jpanel,jscrollpane,Java,Swing,Jframe,Jpanel,Jscrollpane,我想将JScrolpane添加到JPanel中,但没有出现。在JLabel中,它工作得很好,而且非常简单。我正在使用JPanel,因为我会在我的程序中添加一些图像处理的东西。这是我的代码: public void draw(){ panel=new JPanel(){ protected void paintComponent(Graphics g){ Graphics g2 = g.create(); g2.drawImag

我想将JScrolpane添加到JPanel中,但没有出现。在JLabel中,它工作得很好,而且非常简单。我正在使用JPanel,因为我会在我的程序中添加一些图像处理的东西。这是我的代码:

public void draw(){  
 panel=new JPanel(){
        protected void paintComponent(Graphics g){
            Graphics g2 = g.create();
            g2.drawImage(image, 0, 0, this);
            g2.dispose();             
        }         
 };   
 panel.setBorder(BorderFactory.createEtchedBorder());
 panel.setPreferredSize(new Dimension(400, 330));
 s=new JScrollPane(panel);
 s.setPreferredSize(new Dimension(400,285));
 this.getContentPane().add(s,BorderLayout.CENTER);
 add(panel);
 revalidate();  
 repaint();     
 }
public void draw(){
 panel=new JPanel(new BorderLayout()){
 @Override
        protected void paintComponent(Graphics g){
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.drawImage(img, 0, 0, null);
        }         
 };   
 panel.setBounds(0, 0, img.getWidth(), img.getHeight());
 panel.setPreferredSize(new Dimension(img.getWidth(),obraz.getHeight()));
 JScrollPane scrolls=new JScrollPane(panel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

 add(scrolls);
 validate();  
 repaint();     
 }
您正在将JPanel添加到GUI中,而不是JScrollPane,因此,如果滚动窗格没有添加到任何地方,您真的不应该期望看到任何滚动窗格

解决方案:将保存JPanel的JScrollPane添加到GUI中,而不是JPanel本身

您正在将JPanel添加到GUI中,而不是JScrollPane,因此,如果滚动窗格没有添加到任何地方,您真的不应该期望看到任何滚动窗格

解决方案:将保存JPanel的JScrollPane添加到GUI中,而不是JPanel本身

如果不尊重绘制链,请调用super.paintComponent作为重写的paintComponent方法中的第一个调用。i、 e

@Override
protected void paintComponent(Graphics g){ 
      super.paintComponent(g); 
      //draw here
}
或者可能出现视觉伪影

还要注意@Override注释,它应该与被重写的方法一起使用,以便获得编译器检查是否正确重写该方法的优势

不需要getContentPane.add。。只需在JFrame实例上调用add作为add。。随着。。和设置布局。。已转发到JFrames内容窗格

出于任何原因扩展JFrame也不是一个好主意,只需创建一个实例并使用它,即:

JFrame frame=new JFrame("Title here");
...
frame.add(..);
...
frame.pack();
frame.visible(true);
同时绘制传递到paintComponent g的图形对象不要在paintComponent中创建自己的图形对象。当然,除非您是出于以下评论中提到的@HFOE的原因而这样做:

drawImage中不需要此参数。。除非您的JPanel在ImageObserver上实现,否则在绘制时图像可能无法完全加载。只需使用null

至于上面的樱桃,就用一些,如图所示。这将允许绘制质量更好的图像和文本

如果不尊重绘制链,请调用super.paintComponent作为重写的paintComponent方法中的第一个调用。i、 e

@Override
protected void paintComponent(Graphics g){ 
      super.paintComponent(g); 
      //draw here
}
或者可能出现视觉伪影

还要注意@Override注释,它应该与被重写的方法一起使用,以便获得编译器检查是否正确重写该方法的优势

不需要getContentPane.add。。只需在JFrame实例上调用add作为add。。随着。。和设置布局。。已转发到JFrames内容窗格

出于任何原因扩展JFrame也不是一个好主意,只需创建一个实例并使用它,即:

JFrame frame=new JFrame("Title here");
...
frame.add(..);
...
frame.pack();
frame.visible(true);
同时绘制传递到paintComponent g的图形对象不要在paintComponent中创建自己的图形对象。当然,除非您是出于以下评论中提到的@HFOE的原因而这样做:

drawImage中不需要此参数。。除非您的JPanel在ImageObserver上实现,否则在绘制时图像可能无法完全加载。只需使用null

至于上面的樱桃,就用一些,如图所示。这将允许绘制质量更好的图像和文本


我明白了!对我来说,主要原因是没有布局管理器,也没有声明的大小。这是我的代码:

public void draw(){  
 panel=new JPanel(){
        protected void paintComponent(Graphics g){
            Graphics g2 = g.create();
            g2.drawImage(image, 0, 0, this);
            g2.dispose();             
        }         
 };   
 panel.setBorder(BorderFactory.createEtchedBorder());
 panel.setPreferredSize(new Dimension(400, 330));
 s=new JScrollPane(panel);
 s.setPreferredSize(new Dimension(400,285));
 this.getContentPane().add(s,BorderLayout.CENTER);
 add(panel);
 revalidate();  
 repaint();     
 }
public void draw(){
 panel=new JPanel(new BorderLayout()){
 @Override
        protected void paintComponent(Graphics g){
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.drawImage(img, 0, 0, null);
        }         
 };   
 panel.setBounds(0, 0, img.getWidth(), img.getHeight());
 panel.setPreferredSize(new Dimension(img.getWidth(),obraz.getHeight()));
 JScrollPane scrolls=new JScrollPane(panel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

 add(scrolls);
 validate();  
 repaint();     
 }

但是,如果将来有人想复制这段代码,有一件事是要知道的——Jpanel的大小不会刷新它总是第一张打开的图像的大小,但我有scrolsl,我现在很满意;。非常感谢大家。

我知道了!对我来说,主要原因是没有布局管理器,也没有声明的大小。这是我的代码:

public void draw(){  
 panel=new JPanel(){
        protected void paintComponent(Graphics g){
            Graphics g2 = g.create();
            g2.drawImage(image, 0, 0, this);
            g2.dispose();             
        }         
 };   
 panel.setBorder(BorderFactory.createEtchedBorder());
 panel.setPreferredSize(new Dimension(400, 330));
 s=new JScrollPane(panel);
 s.setPreferredSize(new Dimension(400,285));
 this.getContentPane().add(s,BorderLayout.CENTER);
 add(panel);
 revalidate();  
 repaint();     
 }
public void draw(){
 panel=new JPanel(new BorderLayout()){
 @Override
        protected void paintComponent(Graphics g){
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.drawImage(img, 0, 0, null);
        }         
 };   
 panel.setBounds(0, 0, img.getWidth(), img.getHeight());
 panel.setPreferredSize(new Dimension(img.getWidth(),obraz.getHeight()));
 JScrollPane scrolls=new JScrollPane(panel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

 add(scrolls);
 validate();  
 repaint();     
 }

但是,如果将来有人想复制这段代码,有一件事是要知道的——Jpanel的大小不会刷新它总是第一张打开的图像的大小,但我有scrolsl,我现在很满意;。非常感谢大家。

只要我们提供免费建议,如果您发布sscce就会有所帮助;-:不要调用setPreferredSize。重写getPreferredSize或使用适当的“LayoutManagerµ”。@Guillaume Polet您有部分权利。请看我的答案。@Michal在您的情况下,您显然应该覆盖getPreferredSize并返回您绘制的图像的大小。如果在某个时候你要切换到另一个不同大小的图像,你需要调用的只是重新验证;重新油漆;这一切都会很完美。嗯,这是s.GetPreferedSize的把戏;不起作用只要我们提供免费建议,如果您发布sscce就会有所帮助;-:不要调用setPreferredSize。重写getPreferredSize或使用适当的“LayoutManagerµ”。@Guillaume Polet您有部分权利。请看我的答案。@Michal在您的情况下,您显然应该覆盖getPreferredSize并返回您绘制的图像的大小。如果在某个时候你要切换到另一个不同大小的图像,你需要调用的只是重新验证;重新油漆;这一切都会很完美。嗯,这是s.GetPreferedSize的把戏;不工作如果您可能会对图形对象进行更改,而您不希望这些更改传播到GUI中的其他地方,例如JPanel的子对象中,那么创建一个新的图形对象是可以的。我所说的变化是指
例如设置仿射变换或笔划。否则,1+@hovercraftfullofels+1 good point updated answer accorodying如果您可能会对图形对象进行更改,而您不希望这些更改传播到GUI中的其他地方,例如JPanel的子对象中,则可以创建一个新的图形对象。所谓更改,我指的是设置仿射变换或笔划之类的事情。否则,1+@hovercraftfullofels+1 good point已更新答案,原因是考虑调用revalidate而不是validate考虑调用revalidate而不是validate