【问题标题】:why after painting the image the jcombobox only responds after selecting its item 2 times?为什么在绘制图像后 jcombobox 仅在选择其项目 2 次后才响应?
【发布时间】:2014-03-08 00:01:36
【问题描述】:

这是一个程序,它获取一个链接并在画布上绘制它......但是当它在窗口右侧的 jcombobox 停止工作时,您必须选择它 2 次才能更改为所选数字。我还看到paint和repaint方法非常不稳定,有时图像不会出现,或者当你最大化窗口时它会再次消失。

    package bigProgram;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.io.IOException;
import java.net.URL;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

import java.awt.*;
public class First extends JFrame implements ActionListener,ItemListener
{
     JButton test;
     JTextField fill,fillout;
     String web=null;
     BufferedImage im;
     JPanel cuadro=new JPanel();
     Image out;
     Container cont;
     JComboBox<Integer> scale;
    double mini;
     int x,y;
     int sh,sw;
     String seleccionado;
     Canvas space;
    public First()
      {
         //ventana
         setTitle("Image Scalerprinter");
         setBounds(200,200,700,670);
         setResizable(true);
         this.setDefaultCloseOperation(EXIT_ON_CLOSE);
         BorderLayout fer=new BorderLayout();
         setLayout(fer);

         //espacio para dibujar
         space=new Canvas();
         space.setVisible(false);
         add(space,fer.CENTER);

         //boton
         test=new JButton("Test");
         test.setPreferredSize(new Dimension(60, 40));
         add(test,fer.WEST,0);
         test.setActionCommand("T");
         test.addActionListener(this);


         //texto IN
         fill=new JTextField();
         fill.setPreferredSize(new Dimension(200,20));
         add(fill,fer.NORTH,1);

         //texto OUT
         fillout=new JTextField();
         fillout.setPreferredSize(new Dimension(200,20));
         add(fillout,fer.SOUTH,2);


         //opcion para escalarlo
           scale=new JComboBox<Integer>();
           scale.setPreferredSize(new Dimension(50,40));
           for(int i=100;i>0;i--)
           {
               scale.addItem(i);
           }
           add(scale,fer.EAST);
           scale.addItemListener(this);



         setVisible(true);
      }

    ///accion para cerrar
    private void setDefaultCloseOperation(Object exit)
    {

    }





    //metodo para borrar
    public void clearRect()

        {
            repaint();
        }

    //accion del boton
    @Override
    public void actionPerformed(ActionEvent e) 
      {


        if(e.getActionCommand().equals("T"))
         {

             if(fill.getText()!=null)

             {
                 web=fill.getText();

            try 
                {

                  URL r=new URL(web);
                  im =ImageIO.read(r);
                  System.out.println("yes");
                  out= im.getScaledInstance(500, 500, Image.SCALE_SMOOTH);
                  space.repaint();


                }

            catch (IOException e1)

                {

                  e1.printStackTrace();

                }

            }

         }


      }

    //aacion para el scale
        public void itemStateChanged(ItemEvent e) {

            if (e.getSource()==scale)
            {   
                mini=(int) e.getItem();//esta funcionando!
                double size=mini/100;

                scale.setName(getName());


                double sh= out.getHeight(null)*size;
                sw=(int) (out.getWidth(null)*size);

                System.out.println("real size:"+out.getHeight(null)+" height\n "+
                out.getWidth(null)+" width "+"new: "+sh+" and "+sw);




                out.getScaledInstance(sw, (int) sh,Image.SCALE_FAST);

                repaint();
                setVisible(true);
            }
        }

     //metodo para pintar cosas
     public void paint (Graphics g)
        {
          x=100;
          y=100;


         g.drawImage(out, x,y,null);



        }






     public static void main(String[] args)
        {

         First one=new First();
         //"http://www.downtoearthservices.co.uk/resources/tree2.gif" this is the link to paste in the jtextfield


        }

【问题讨论】:

    标签: java swing awt paint jcombobox


    【解决方案1】:
    1. 不调用 super.paint(g) 会破坏绘制链,这会留下绘制伪像。

    2. 同样,您不应该在像JFrame 这样的顶级容器上进行绘制,因为它们不是双缓冲的,并且它们已经在组件中承担了绘制的负载。而是在JPanelJComponent 上绘制并覆盖paintComponent 并调用super.paintComponent()

      public class First extends JPanel ... {
          ...
          @Override
          protected void paintComponent(Graphics g) {
              super.paintComponent(g);
              x = 100;
              y = 100;
              g.drawImage(out, x, y, null);
          }
          ...
      }
      
    3. 当在 JPanel 上绘画时,您应该覆盖 getPreferredSize() 和只是 pack() 框架容器。

      @Override 
      public Dimension getPreferredSize() {
          return new Dimension(700, 670);
      }
      
    4. Event Dispatch Thread 运行 Swing 应用程序

      public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable(){
              public void run() {
                  First one = new First();
                  JFrame frame = new JFrame("Frame");
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  frame.add(one);
                  frame.pack();
                  frame.setLocationRelativeTo(null);
                  frame.setVisible(true);
              }
          });
      }
      

    【讨论】:

      【解决方案2】:
      mini = (int) e.getItem();//esta funcionando!
      

      导致编译错误:

      inconvertible types:  required: int   found: java.lang.Object
      

      不要尝试运行无法正确编译的源代码。这将导致不可预知的行为。

      确实编译干净:

      mini = (Integer)(e.getItem());//esta funcionando!
      

      【讨论】:

        猜你喜欢
        • 2020-07-02
        • 2021-05-21
        • 2015-04-06
        • 2016-06-07
        • 1970-01-01
        • 1970-01-01
        • 2019-05-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多