2015-07-13 31 views
0

我一直在尝试将Java表单元素(如textField和passwordField)添加到全屏独占模式框架中。我遇到的问题是,当我运行代码时,我的表单元素没有完全显示,或者根本没有显示,直到我实际点击它们。Java表单元素直到激活时才显示出来,即点击

这里是我的代码:

Master.java

import java.awt.Color; 
import java.awt.Font; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.Image; 
import java.awt.Rectangle; 
import java.awt.RenderingHints; 
import java.awt.Toolkit; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.net.URL; 

import javax.swing.ImageIcon; 
import javax.swing.JFrame; 

public class Master extends JFrame { 

    private static final long serialVersionUID = -4927941474660261348L; 
    static GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    static GraphicsDevice gd = ge.getDefaultScreenDevice(); 
    static int WIDTH = gd.getDisplayMode().getWidth(); 
    static int HEIGHT = gd.getDisplayMode().getHeight(); 
    static Toolkit toolkit = Toolkit.getDefaultToolkit(); 
    static Graphics2D g2d = null; 
    static FontMetrics metrics = null; 
    static URL vignetteURL = null; 
    static Image vignette = null; 
    static Rectangle red = new Rectangle(WIDTH - 35, 0, 35, 35); 

    public Master() { 
     super("Project Zenith"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setLocationRelativeTo(null); 
     getContentPane().setLayout(null); 
     setUndecorated(true); 
     setResizable(false); 
     gd.setFullScreenWindow(this); 
     repaint(); 

     setIconImage(new ImageIcon(getClass().getResource("images/hex.png")).getImage()); 
     vignetteURL = getClass().getResource("images/vignette2.png"); 

     addMouseListener(new MouseListener() { 
      @Override 
      public void mouseClicked(MouseEvent e) { 
       if(e.getX() >= red.getX() && e.getY() <= red.getHeight()) { 
        closeClicked(); 
       } 
      } 

      @Override 
      public void mouseEntered(MouseEvent arg0) { 

      } 

      @Override 
      public void mouseExited(MouseEvent arg0) { 

      } 

      @Override 
      public void mousePressed(MouseEvent arg0) { 

      } 

      @Override 
      public void mouseReleased(MouseEvent arg0) { 

      }   
     }); 
    } 

    public void update(Graphics g) { 
     paint(g); 
    } 

    public void paint(Graphics g) { 
     g2d = (Graphics2D) g; 
     vignette = toolkit.getImage(vignetteURL); 
     g2d.clearRect(0, 0, getWidth(), getHeight()); 
     g2d.setFont(new Font("Bebas Neue", Font.PLAIN, 25)); 
     metrics = g2d.getFontMetrics(); 
     g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
     g2d.setColor(new Color(168, 168, 168, 200)); 
     g2d.drawString("Project Zenith", 10, HEIGHT - 10); 
     g2d.setColor(new Color(0xFFA6A6)); 
     g2d.fill(red); 
     g2d.drawImage(vignette, 0, 0, WIDTH, HEIGHT, this); 

    } 

    public void closeClicked() { 
     System.exit(0); 
    } 
} 

Login.java

import java.awt.Color; 
import java.awt.Font; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.RoundRectangle2D; 

import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JPasswordField; 
import javax.swing.JTextField; 

public class Login extends Master { 
    private static final long serialVersionUID = 1L; 
    static Master l; 
    static JTextField username; 
    static JTextField password; 
    static Graphics2D g2d = null; 
    static FontMetrics metrics = null; 
    static RoundRectangle2D loginRect = new RoundRectangle2D.Float((WIDTH/2) - ((WIDTH/4)/2), (HEIGHT/2) - ((HEIGHT/4)/2), (WIDTH/4), (HEIGHT/4), 20, 20); 

    Login() { 
     l = this; 
     Font inputFont = new Font("Calibri", Font.PLAIN, 15); 

     username = new JTextField(); 
     username.setBounds((WIDTH/2) - (((int) loginRect.getY() - 10)/2), (int) loginRect.getY() + 60, (int) loginRect.getY() - 10, 18); 
     username.setFont(inputFont); 
     username.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
     username.setEditable(true); 
     username.setBackground(new Color(0xE6E6E6)); 
     //username.setVisible(true); 
     getContentPane().add(username); 

     password = new JPasswordField(); 
     password.setBounds((WIDTH/2) - (((int) loginRect.getY() - 10)/2), (int) loginRect.getY() + 110, (int) loginRect.getY() - 10, 18); 
     password.setFont(inputFont); 
     password.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
     password.setEditable(true); 
     password.setBackground(new Color(0xE6E6E6)); 
     //password.setVisible(true); 
     getContentPane().add(password); 

     JButton loginButton = new JButton("Login"); 
     loginButton.setBounds((WIDTH/2) - 40, (int) loginRect.getY() + 155, 80, 20); 
     loginButton.setFont(inputFont); 
     loginButton.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
     loginButton.setBackground(new Color(0xE6E6E6)); 
     //loginButton.setVisible(true); 
     loginButton.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       System.out.println(username.getText()); 
      } 
     }); 
     getContentPane().add(loginButton); 
     repaint(); 
     setVisible(true); 

    } 

    public void paint(Graphics g) { 
     super.paint(g); 
     g2d = (Graphics2D) g; 
     metrics = g2d.getFontMetrics(); 
     g2d.setColor(Color.WHITE); 
     g2d.fill(loginRect); 
     g2d.setColor(new Color(0xA8A8A8)); 
     g2d.drawString("Access Terminal", (Master.WIDTH/2) - (metrics.stringWidth("Access Terminal")/2), (int) loginRect.getY() + metrics.getHeight() + 2); 
    } 

    public static void main(String [] args) { 
     new Login(); 
    } 
} 
+0

不要覆盖顶级容器的'update'或'paint'。通过调用'super.paint'来确保你正在维护绘画链的完整性。避免使用'空'布局,像素完美的布局是现代UI设计中的幻想。影响组件的个体大小的因素太多,其中没有一个可以控制。Swing被设计为与布局管理者一起工作,放弃这些将导致问题和问题的终结,你将花费越来越多的时间来尝试纠正 – MadProgrammer

+1

对于尚未显示的组件调用“repaint”没有意义在屏幕上 – MadProgrammer

+0

'静态'不是你的朋友,它不是你通过其启用交叉对象通信的手段,它是一种手段,通过它你可以拍摄自己的脚并想知道为什么你会跛行... – MadProgrammer

回答

0

开始采取看看Painting in AWT and SwingPerforming Custom Painting绘画在Swing中是如何工作的说明。

的基本问题是:

  1. 你打破绘画链
  2. 你画过的子组件

这是(的原因是多方面的)一个,为什么你不应该” t覆盖顶级容器的paint。相反,通过使用JPanel并重写它的paintComponent(主叫super.paintComponent你执行任何自定义涂装前)

您还应该采用适当的布局管理器,以更好地处理决议和字体渲染要求的​​差异开始。

看一看Laying Out Components Within a Container更多细节

凭借小聪明的规划,你可以做一些漂亮的东西提前

enter image description here

现在,很明显这不是全屏,但这点很重要,您现在可以取消注释行gd.setFullScreenWindow(frame);,它会通过布局经理的力量自动地重新整理自己。

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Font; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.awt.Rectangle; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.geom.RoundRectangle2D; 
import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JPasswordField; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.border.EmptyBorder; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 
       GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
       GraphicsDevice gd = ge.getDefaultScreenDevice(); 

       Login login = new Login(); 
       JFrame frame = new JFrame("Project Zenith"); 
       frame.setUndecorated(true); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(login); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
//    gd.setFullScreenWindow(frame); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public static class Master extends JPanel { 

     private static final long serialVersionUID = -4927941474660261348L; 

     private Rectangle closeRect; 

     public Master() { 

      addMouseListener(new MouseListener() { 
       @Override 
       public void mouseClicked(MouseEvent e) { 
        if (e.getX() >= closeRect.getX() && e.getY() <= closeRect.getHeight()) { 
         closeClicked(); 
        } 
       } 

       @Override 
       public void mouseEntered(MouseEvent arg0) { 

       } 

       @Override 
       public void mouseExited(MouseEvent arg0) { 

       } 

       @Override 
       public void mousePressed(MouseEvent arg0) { 

       } 

       @Override 
       public void mouseReleased(MouseEvent arg0) { 

       } 
      }); 
     } 

     @Override 
     public void invalidate() { 
      super.invalidate(); 
      closeRect = new Rectangle(getWidth() - 35, 0, 35, 35); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g; 
      g2d.setFont(new Font("Bebas Neue", Font.PLAIN, 25)); 
      g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
      g2d.setColor(new Color(168, 168, 168, 200)); 
      FontMetrics fm = g2d.getFontMetrics(); 
      int y = (getHeight() - fm.getHeight()) + fm.getAscent(); 
      g2d.drawString("Project Zenith", 10, y); 
      g2d.setColor(new Color(0xFFA6A6)); 
      g2d.fill(closeRect); 
     } 

     public void closeClicked() { 
      System.exit(0); 
     } 
    } 

    public static class Login extends Master { 

     private static final long serialVersionUID = 1L; 
     private JTextField username; 
     private JTextField password; 


     Login() { 
      Font inputFont = new Font("Calibri", Font.PLAIN, 15); 

      setLayout(new GridBagLayout()); 

      JPanel content = new JPanel(new GridBagLayout()) { 
       @Override 
       protected void paintComponent(Graphics g) { 
        super.paintComponent(g); 
        RoundRectangle2D loginRect = new RoundRectangle2D.Float(0, 0, getWidth() - 1, getHeight() - 1, 20, 20); 
        Graphics2D g2d = (Graphics2D) g; 
        g2d.setColor(Color.WHITE); 
        g2d.fill(loginRect); 
        g2d.setColor(new Color(0xA8A8A8)); 
        g2d.draw(loginRect); 
       } 
      }; 
      content.setBorder(new EmptyBorder(20, 20, 20, 20)); 

      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridwidth = GridBagConstraints.REMAINDER; 
      gbc.insets = new Insets(0, 0, 25, 0); 

      gbc.gridx = 0; 
      gbc.gridy = 0; 

      JLabel label = new JLabel("Access Terminal"); 
      label.setFont(new Font("Bebas Neue", Font.PLAIN, 25)); 
      label.setForeground(new Color(0xA8A8A8)); 

      content.add(label, gbc); 

      gbc.gridy++; 
      username = new JTextField(25); 
      username.setFont(inputFont); 
      username.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
      username.setEditable(true); 
      username.setBackground(new Color(0xE6E6E6)); 
      //username.setVisible(true); 
      content.add(username, gbc); 

      gbc.gridy++; 
      password = new JPasswordField(25); 
      password.setFont(inputFont); 
      password.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
      password.setEditable(true); 
      password.setBackground(new Color(0xE6E6E6)); 
      //password.setVisible(true); 
      content.add(password, gbc); 

      gbc.gridy++; 

      JButton loginButton = new JButton("Login"); 
      loginButton.setFont(inputFont); 
      loginButton.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
      loginButton.setBackground(new Color(0xE6E6E6)); 
      loginButton.addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent e) { 
        System.out.println(username.getText()); 
       } 
      }); 
      content.add(loginButton, gbc); 

      add(content); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(400, 400); 
     } 
    } 
} 

基本上,你Login观点,我用的混合成分,生成“圆角的边框”的效果,营造出JPanel并重写它的paintComponent方法绘制的效果。这为我提供了来自子组件的布局信息,以便确定该效果应该有多大。然后将其添加到Login面板本身中,并通过使用布局管理器,它全部获得中心

+0

非常感谢老兄:D – JacoJazz

+0

很高兴它可以帮助 – MadProgrammer

相关问题