除非在主

时间:2017-03-03 19:24:22

标签: java swing class user-interface jframe

我有一个用图像创建JFrame的类,但每次创建类并运行方法来实例化它时,它都不会出现。但是,我注意到如果我要创建完全相同的类并在main中运行相同的方法,那么框架就会出现。

这是我尝试创建的JFrame类的大部分代码:

    JFrame myFrame= new JFrame();
    public void CreateFrame()
    {       
        JLabel background=new JLabel(new ImageIcon("image.jpg"));

        myFrame.add(background);

        background.setLayout(new FlowLayout());

        myFrame.setLayout(new GridLayout(1,1));
        myFrame.setSize(360,250);
        myFrame.setUndecorated(true);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        myFrame.setLocation((dim.width/2-170), dim.height/2-125);
        myFrame.pack();
        myFrame.setVisible(true);
    }

如果我运行代码

MyClass mc = new MyClass();
mc.CreateFrame();

在另一个类的方法中它没有出现。但是,如果我在main方法中运行完全相同的代码,它就可以工作。

例如,这不起作用:

示例1

public class otherClass extends JFrame
{
    public void MethodA()
    {
        MyClass mc = new MyClass();
        mc.CreateFrame();
    }

    public static void main(String[] args)
    {
        otherClass oc = new otherClass();
        oc.MethodA();
    }
}

但这确实有效

示例2

public class otherClass extends JFrame
{
    public void MethodA()
    {
        //CODE
    }

    public static void main(String[] args)
    {
        otherClass oc = new otherClass();
        oc.MethodA();

        MyClass mc = new MyClass();
        mc.CreateFrame();
    }
}

谁能看到我哪里出错了?对不起,如果一个愚蠢的错误,我仍然要掌握Java。 感谢

修改

import javax.swing.ImageIcon;
import javax.swing.JWindow;
import javax.swing.JLabel;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import javax.imageio.ImageIO;
import java.util.Timer;
import java.util.Date;
import javax.swing.JFrame;

public class MyClass
 {
    JFrame homeFrame = new JFrame();
    public void createFrame()
    {       

    JLabel background=new JLabel(new ImageIcon("images.jpg"));

    myFrame.add(background);

    background.setLayout(new FlowLayout());

    myFrame.setLayout(new GridLayout(1,1));
    myFrame.setSize(360,250);
    myFrame.setUndecorated(true);
    myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
    myFrame.setLocation((dim.width/2-170), dim.height/2-125);
    myFrame.setAlwaysOnTop(true);
    myFrame.pack();
    myFrame.setVisible(true);
    durationOfTime();
}

public void durationOfTime()
{
    MainProgram mp = new MainProgram();
    long startTime = System.currentTimeMillis();
    long elapsedTime = 0L;
    int count =0;
    while (elapsedTime < 2*1000) 
    {
        if(count==0)
        {
            mp.launchInitiation();
        }
        count+=1;

        elapsedTime = (new Date()).getTime() - startTime;
    }
    myFrame.setVisible(false);
    mp.homeFrame.setVisible(true);
}

  public static void main(String[] args) 
  {
    MyClass mc = new MyClass();
    mc.createFrame();
  }
}

来自JFrame尝试制作的类的完整代码。我正在尝试将此JFrame用作启动画面,但无论我调用哪个类

MyClass mc = new MyClass();
mc.createFrame();

来自,它只是没有出现。在我的主GUI出现之前经过两秒钟,但是这个方法应该在登录类型框架中调用。但是,我已经使用空白的JFrame / GUI对其进行了测试,以便在按钮点击时显示,但仍然没有出现。

EDIT2

我之前也试过@ http://examples.oreilly.com/jswing2/code/ch08/SplashScreen.java这个SplashScreen示例,但是我无法让它工作(同样的问题,从main调用时出现,但从动作监听器调用时不出现)

import java.awt.*;
import javax.swing.*;

public class SplashScreen extends JWindow {
  private int duration;
  public SplashScreen(int d) {
    duration = d;
  }

  // A simple little method to show a title screen in the center
  // of the screen for the amount of time given in the constructor
  public void showSplash() {
    JPanel content = (JPanel)getContentPane();
    content.setBackground(Color.white);

    // Set the window's bounds, centering the window
    int width = 450;
    int height =115;
    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (screen.width-width)/2;
    int y = (screen.height-height)/2;
    setBounds(x,y,width,height);

    // Build the splash screen
    JLabel label = new JLabel(new ImageIcon("oreilly.gif"));
    JLabel copyrt = new JLabel
      ("Copyright 2002, O'Reilly & Associates", JLabel.CENTER);
    copyrt.setFont(new Font("Sans-Serif", Font.BOLD, 12));
    content.add(label, BorderLayout.CENTER);
    content.add(copyrt, BorderLayout.SOUTH);
    Color oraRed = new Color(156, 20, 20,  255);
    content.setBorder(BorderFactory.createLineBorder(oraRed, 10));

    // Display it
    setVisible(true);

    // Wait a little while, maybe while loading resources
    ClassToLoad ctl = new ClassToLoad();
    try {
    Thread.sleep(duration); 
    ctl.initiate();
    } catch (Exception e) {}

    setVisible(false);
  }

  public void showSplashAndExit() {
    showSplash();
    System.exit(0);
  }

  public static void main(String[] args) {
    // Throw a nice little title page up on the screen first
    SplashScreen splash = new SplashScreen(10000);
    // Normally, we'd call splash.showSplash() and get on with the program.
    // But, since this is only a test...
    splash.showSplashAndExit();
  }
}

我在ClassToLoad的行中添加了代码,并且在动作监听器上调用了这个SplashScreen,会发生什么是程序等待我告诉它的2秒,没有框架出现,然后是我想要的主类在启动屏幕可见负载时加载。我首先尝试了这种方法,但这不起作用,导致我使用上面编辑的代码

编辑3

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TestFrame extends JFrame implements ActionListener 
{
    JPanel thePanel = new JPanel(null); //layout
    JButton button = new JButton();

 public void startGUI()
 {
    this.setLayout(new GridLayout(1,1));
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    

    CREATEMYPANEL();
    this.add(thePanel);

    this.setTitle("NO_TITLE_SET");
    this.setSize(400,400);
    this.setVisible(true);
    this.setResizable(true);
 }

 public void CREATEMYPANEL()
 {
    button.setLocation(242,151);
    button.setSize(100,50);
    button.addActionListener(this);
    button.setText("button");
    thePanel.add(button);

 }

 public void actionPerformed(ActionEvent e)
 {
    if(e.getSource()==button)
    {
         System.out.println("button has been pressed ");
         SplashScreen splash = new SplashScreen(1000);
         splash.showSplash();
    }
 }

 public static void main(String[] args )

 {
    TestFrame tf = new TestFrame();
    tf.startGUI();
 }
}  

我从中调用启动画面的示例。仍然无法正常工作。另外,请注意我正在加载的图像是本地图像

为不良问题格式道歉

2 个答案:

答案 0 :(得分:3)

除了我注意到的一些细节之外,你的代码对我有用:

  1. 您正在致电setSize(...),然后致电pack()。可能你的图像没有被加载,因此你的JFrame的大小为0,0。(因此它看起来似乎永远不会出现)。 .pack().setSize(...)是互斥的。

  2. 您已将JLabel的布局管理器设置为FlowLayout,但从不向其添加任何内容。 (您可以安全地删除它)

  3. 如果您想在2秒后处理JFrame,我会看到您正在导入java.util.Timer,那么您应该使用javax.swing.Timer代替Event Dispatch Thread (EDT)。否则你可能会遇到与线程相关的问题。

  4. 也不要忘记将程序放在Splashscreen上,因为Swing不是线程安全的

  5. 按照上述建议,您可以使用以下代码:

    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    
    public class SplashscreenSample {
        private JFrame myFrame;
        private JLabel background;
        private Timer timer;
    
        public void createFrame() {
    
            timer = new Timer(2000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    myFrame.dispose();
                    @SuppressWarnings("serial")
                    JFrame frame = new JFrame(getClass().getSimpleName()) {
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(200, 200);
                        }
                    };
                    frame.pack();
                    frame.setVisible(true);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    timer.stop();
                }
            });
    
            myFrame = new JFrame(getClass().getSimpleName());
            try {
                background = new JLabel(new ImageIcon(new URL("http://cdn.bulbagarden.net/upload/thumb/6/6b/175Togepi.png/250px-175Togepi.png")));
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
    
            myFrame.add(background);
    
            timer.setInitialDelay(2000);
            timer.start();
    
            myFrame.setLayout(new GridLayout(1, 1));
            myFrame.setUndecorated(true);
            myFrame.setAlwaysOnTop(true);
            myFrame.pack();
            Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
            myFrame.setLocation((dim.width/2-170), dim.height/2-125);
            myFrame.setVisible(true);
            myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> new SplashscreenSample().createFrame()); 
        }
    }
    

    或者您可以使用Array#detect类......

    例如:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.Toolkit;
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import javax.swing.BorderFactory;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JWindow;
    
    public class SplashScreen extends JWindow {
        private int duration;
    
        public SplashScreen(int d) {
            duration = d;
        }
    
        // A simple little method to show a title screen in the center
        // of the screen for the amount of time given in the constructor
        public void showSplash() {
            ImageIcon icon = null;
            try {
                icon = new ImageIcon(new URL("http://www.cqsisu.com/data/wallpapers/5/718448.gif"));
            } catch (MalformedURLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
    
            JPanel content = (JPanel) getContentPane();
            content.setBackground(Color.white);
    
            // Set the window's bounds, centering the window
            int width = icon.getIconWidth();
            int height = icon.getIconHeight();
            Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
            int x = (screen.width - width) / 2;
            int y = (screen.height - height) / 2;
    
            setBounds(x, y, width, height);
    
            // Build the splash screen
            JLabel label = new JLabel(icon);
            JLabel copyrt = new JLabel("Copyright 2002, O'Reilly & Associates", JLabel.CENTER);
            copyrt.setFont(new Font("Sans-Serif", Font.BOLD, 12));
            content.add(label, BorderLayout.CENTER);
            content.add(copyrt, BorderLayout.SOUTH);
            Color oraRed = new Color(156, 20, 20, 255);
            content.setBorder(BorderFactory.createLineBorder(oraRed, 10));
    
            // Display it
            setVisible(true);
    
            // Wait a little while, maybe while loading resources
            loadResources();
    
            setVisible(false);
        }
    
        public void loadResources() {
            TestFrame tf = new TestFrame();
            try {
                Thread.sleep(duration);
                tf.startGUI();
            } catch (Exception e) {
            }
        }
    
        public static void main(String[] args) {
            SplashScreen splash = new SplashScreen(10000);
            splash.showSplash();
        }
    }
    

答案 1 :(得分:0)

尝试在类的构造函数中创建和设置可见的框架 可能是因为你的程序正在计算

 while (elapsedTime < 2*1000) 
    {
        if(count==0)
        {
            mp.launchInitiation();
        }
        count+=1;

        elapsedTime = (new Date()).getTime() - startTime;
    }

它阻塞了所说的2秒并等待这个方法完成,返回到create方法然后才完成那个?

似乎这可能是一个更好的评论,但我需要50个代表出于某种原因发表评论。