在独奏线程上刷新Gui

时间:2013-02-06 12:39:13

标签: java multithreading swing repaint paintcomponent

我编码一个应用程序,我想在地图上绘制一些标记和图片。但在这里我有问题。当我按下按钮iam启动线程延迟30毫秒。但实际上它看起来这个任务正在运行在主线程上导致gui停止刷新,不能用它做任何事情。 继承我的代码

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;

import javax.swing.JInternalFrame;
import javax.swing.JPanel;

public class MapDrawer extends JPanel
{
     Graphics testGrafika;
     DrawerThread drawingThread;

    public MapDrawer(JPanel drawPanel)
    {
        drawPanel.add(this);
        testGrafika=drawPanel.getGraphics();    
        paintComponent(testGrafika);
        drawingThread=new DrawerThread();
        drawingThread.run();            
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponents(g);
        this.setBackground(Color.WHITE);
        g.setColor(Color.BLUE);
        g.fillRect(10, 25, 200, 200);
    }

    public Graphics getGraphics()
    {
        return testGrafika;         
    }

    public class DrawerThread extends Thread implements Runnable
    {   
        @Override
        public void run()
        {
            while(true)
            {
                repaint();
                try {
                    DrawerThread.sleep(30);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

这是我的GUI类:

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import javax.swing.JButton;
import java.awt.CardLayout;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;

import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.FlowLayout;
import javax.swing.border.EtchedBorder;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import org.eclipse.wb.swing.FocusTraversalOnArray;

import soft.MapDrawer;
import soft.MapView;

import java.awt.Component;
import javax.swing.JToggleButton;
import javax.swing.JRadioButton;
import javax.swing.JInternalFrame;
import java.awt.Canvas;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Dimension;
import javax.swing.JLayeredPane;

public class MainWindow {

    private JFrame frame;
    private JMenu MenuBasicActions;
    private JInternalFrame mapFrameRef;
    private JPanel drawPanelRef;

    /**
     * Launch the application.
     */
    public static void main(String[] args)
    {   
        EventQueue.invokeLater(new Runnable()

        {
            public void run() 
            {
                try 
                {
                    MainWindow window = new MainWindow();
                    window.frame.setVisible(true);
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });

    }

    /**
     * Create the application.
     */
    public MainWindow()
    {
        initialize();               
    }

    public JFrame getMainFrame()
    {
        return frame;
    }

    public JPanel getDrawPanel()
    {
        return drawPanelRef;    
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setVisible(true);
        frame.setBounds(100, 100, 1024, 768);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);           

        JMenuBar menuBarUpper = new JMenuBar();
        frame.setJMenuBar(menuBarUpper);

        MenuBasicActions = new JMenu("GPS Settings");
        menuBarUpper.add(MenuBasicActions);

        JMenuItem mntmNewMenuItem = new JMenuItem("New menu item");
        MenuBasicActions.add(mntmNewMenuItem);

        JMenuItem mntmNewMenuItem_1 = new JMenuItem("New menu item");
        MenuBasicActions.add(mntmNewMenuItem_1);

        JMenuItem mntmNewMenuItem_2 = new JMenuItem("New menu item");
        MenuBasicActions.add(mntmNewMenuItem_2);

        JMenu DevicesMenu = new JMenu("Devices");
        menuBarUpper.add(DevicesMenu);

        JMenuItem mntmNewMenuItem_3 = new JMenuItem("New menu item");
        DevicesMenu.add(mntmNewMenuItem_3);

        JMenuItem mntmNewMenuItem_4 = new JMenuItem("New menu item");
        DevicesMenu.add(mntmNewMenuItem_4);

        JMenu HelpMenu = new JMenu("Help");
        menuBarUpper.add(HelpMenu); 

        JToolBar toolBar = new JToolBar();
        toolBar.setOrientation(SwingConstants.VERTICAL);
        frame.getContentPane().add(toolBar, BorderLayout.WEST);

        JButton btnNewButton_1 = new JButton("New button");
        btnNewButton_1.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent arg0)
            {
                paint();
            }
        });
        toolBar.add(btnNewButton_1);


        JButton btnNewButton = new JButton("New button");
        toolBar.add(btnNewButton);

        JButton btnNewButton_2 = new JButton("New button");
        toolBar.add(btnNewButton_2);

        JButton btnNewButton_3 = new JButton("New button");
        toolBar.add(btnNewButton_3);
        toolBar.setFocusTraversalPolicy(new FocusTraversalOnArray(new Component[]{btnNewButton_1, btnNewButton}));

        JInternalFrame mapFrame = new JInternalFrame("Military Tracking System");
        mapFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.getContentPane().add(mapFrame, BorderLayout.CENTER);
        mapFrame.setVisible(true);

        JPanel drawPanel = new JPanel();
        drawPanel.setOpaque(false);
        mapFrame.setGlassPane(drawPanel);
        drawPanel.setVisible(true);

        drawPanel.setBorder(null);
        //mapFrame.getContentPane().add(drawPanel, BorderLayout.CENTER);

        frame.setFocusTraversalPolicy(new FocusTraversalOnArray(new Component[]{frame.getContentPane(), toolBar, btnNewButton_1, btnNewButton, btnNewButton_2, btnNewButton_3, menuBarUpper, MenuBasicActions, mntmNewMenuItem, mntmNewMenuItem_1, mntmNewMenuItem_2, DevicesMenu, mntmNewMenuItem_3, mntmNewMenuItem_4, HelpMenu}));

        MapView hlavnaMapa=new MapView();
        hlavnaMapa.Init(mapFrame);  
        mapFrameRef=mapFrame;
        drawPanelRef=drawPanel;
    }

    public void paint()
    {
        MapDrawer drawer=new MapDrawer(drawPanelRef);
        //drawer.paintComponent(drawer.getGraphics());          
    }
}

我想做的是在一个线程上运行gui并在另一个线程上绘制对象,所以我可以控制gui。

1 个答案:

答案 0 :(得分:1)

要启动Thread,您应该调用drawingThread.start();而不是run()

然后

start()将启动一个新线程并在此线程内调用方法run()。如果您改为呼叫run(),它将在与呼叫者相同的线程上运行。