【问题标题】:Textfield added to Jframe disappears when the graphics are redrawn重绘图形时,添加到 Jframe 的文本字段消失
【发布时间】:2015-08-19 19:44:41
【问题描述】:

我在使用 JFrame 文本字段时遇到问题。
我正在尝试制作文字游戏,但问题是当我尝试创建文本字段以设置输入然后检查它是否是正确的单词时,我已经涵盖了单词 thing。
问题是,当我尝试添加 Textfield 时,它会在我将内容渲染到 JFrame 时消失。

public teksti() {

    setTitle("Hirsipuu");
    setSize(leveys,korkeus);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);
    setVisible(true);
    setLocationRelativeTo(null);
    setBackground(Color.white);
    jp.add(tf); // adding JtextField (JTextField tf = new JTextField(30);)
    add(jp);        
}

而我的render() 是这样的(仅用于测试目的)。

private void render() {
    BufferStrategy bs = this.getBufferStrategy(); // tehdään uusi bufferi

    if (bs == null) {
        createBufferStrategy(3);
        return;
    }

    int R = (int) (Math.random( )*256);
    int G = (int)(Math.random( )*256);
    int B= (int)(Math.random( )*256);
    Color randomColor = new Color(R, G, B);
    Graphics g = bs.getDrawGraphics();

    g.drawString("Arvaa sana", 100 , 100);

    g.setColor(Color.white);
    g.fillRect(0, 50, leveys, korkeus);
    g.setColor(randomColor);
    g.setFont(h);
//  g.drawLine(0,0,liikey*2-1,liikex);
    for(int i = 0; i < salat.size(); i ++) {
        g.drawString(salat.get(i),liikex+rand.nextInt(50),liikey+rand.nextInt(50));
    }
    System.out.println(liikex + " " + liikey);

    g.dispose();
    bs.show();
    g.dispose();
}

我可以让文本字段在开始时显示在顶部,但随后它消失了。
有人知道是否有更好的方法吗?

【问题讨论】:

  • 主动渲染 (BufferStrategy) 和 Swing 的被动渲染算法不兼容。您将需要使用 Swing API 或 BufferStrategy,但不能同时使用

标签: java render textfield


【解决方案1】:

这基本上是我现在完成的全部工作。

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class teksti extends JFrame implements Runnable {

/**
 * 
 */
private static final long serialVersionUID = 1L;
ArrayList<String> sanat = new ArrayList<String>();
ArrayList<String> salat = new ArrayList<String>();
String dir =  System.getProperty("user.dir");
String pathname = dir  + "\\src\\kotus_sanat.txt";
Random rand = new Random();
Scanner lukija = new Scanner(System.in);
String syote,salasana,salasana2;
int leveys=500,korkeus=500;
int liikex=300, liikey=300;
Font h = new Font("Helvetica", Font.PLAIN, 18);
JTextField tf = new JTextField(30);
JPanel jp = new JPanel();
JFrame jf = new JFrame();


  public teksti() {

    setTitle("Hirsipuu");
    setSize(leveys,korkeus);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);
    setVisible(true);
    setLocationRelativeTo(null);
    setBackground(Color.white);
    jp.add(tf);
    add(jp);

}

public static void main(String args[]){
     teksti teksti = new teksti();
     teksti.start();

}


private void start() {
    run();

}


public void run() {


    sanat = lataa();
    System.out.println(pathname);

    System.out.println(sanat.size() + " sanaa ladattu..");
    int sanoja=sanat.size();



    for (int i = 0; i < 10; i++){
    salat.add(sanat.get(rand.nextInt(sanoja)));
    }
    System.out.println("salasana on " + salasana);
    long lastTime = System.nanoTime(); // fps sälää
    long timer = System.currentTimeMillis();
    final double ns = 1000000000.0 / 60.0;
    double delta = 0;
    int frames = 0;
    int updates = 0;
    requestFocus();

    boolean running=true;
    while (running){
         long now = System.nanoTime();
         delta += (now-lastTime) / ns;
         lastTime = now;
         while ( delta >= 1) {
            update();
            updates++;
            delta--;    
        }
        render();
         frames++;

         if (System.currentTimeMillis() - timer > 1000){
            timer += 1000;
            setTitle("Hirsipuu"+ "    |    " + updates + " ups " +   frames + " fps" );
            updates = 0;
            frames = 0;
        }   
    }
 }

 private void update() {
    liikex = liikex + 1;
    liikey= liikey - 4;
    if (liikey>korkeus)
        liikey = 1;
    if (liikex>leveys)
        liikex= 1;
    if (liikey<20)
        liikey = korkeus;


 }
 private void render() {
    BufferStrategy bs = this.getBufferStrategy(); // tehdään uusi bufferi

    if (bs == null) {
        createBufferStrategy(3);
        return;
    }


    int R = (int) (Math.random( )*256);
    int G = (int)(Math.random( )*256);
    int B= (int)(Math.random( )*256);
    Color randomColor = new Color(R, G, B);
    Graphics g = bs.getDrawGraphics();



g.drawString("Arvaa sana", 100 , 100);

g.setColor(Color.white);
g.fillRect(0, 50, leveys, korkeus);
    g.setColor(randomColor);
    g.setFont(h);
//  g.drawLine(0,0,liikey*2-1,liikex);
    for(int i = 0; i < salat.size(); i ++) {
    g.drawString(salat.get(i),  liikex+rand.nextInt(50),liikey+rand.nextInt(50));
        }
    System.out.println(liikex + " " + liikey);

 g.dispose();
 bs.show();


  g.dispose();
 }






private void stop() {


}



private void vertaa() {
    System.out.println("Anna sana niin tarkastaan onko se oikea suomenkielinen sana: ");
    syote = lukija.next();

    boolean oikea = false;
    int i = 0;
    int z = 0;
    while (i < sanat.size()) { 
        if (syote.equals(sanat.get(i))) {
            oikea = true;
            System.out.println (syote + " on oikea suomalainen sana.");
            break;

        }
        else{



         }

        }
    if (!oikea) {
        System.out.println(syote + " ei ole oikea suomalainen sana.");
    }


 }



 public ArrayList<String> lataa() {



    String line = null;

    try {

        BufferedReader reader = new BufferedReader(new FileReader(pathname));
        while((line = reader.readLine()) != null){
            sanat.add(line);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return sanat;
    }


}

             vertaa() is not used.

【讨论】:

    【解决方案2】:
    • 不要直接在 JFrame 中绘制
    • 相反,如果您需要绘制背景图像,请在 JPanel 的 paintComponent 方法中进行。这可能比将 BufferStrategy 用于您的目的要好得多。
    • 然后您可以将组件,例如您的 JTextField 添加到此 JPanel。
    • 然后将此 JPanel 添加到您的 JFrame。
    • 始终在您自己的paintComponent 方法覆盖中调用super 的paintComponent 方法。
    • 请注意,切勿处置从 JVM 提供给您的 Graphics 对象,例如传入您的 paintComponent 方法的对象。

    例如:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.GradientPaint;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Paint;
    import javax.swing.*;
    
    public class BackgroundPanel extends JPanel {
       private static final int PREF_W = 800;
       private static final int PREF_H = 600;
       private static final Font PROMPT_FONT = new Font(Font.SANS_SERIF, Font.BOLD,
             24);
       private Paint gradientPaint;
       private JTextField textField = new JTextField(20);
    
       public BackgroundPanel() {
          int red = (int) (Math.random() * 256);
          int green = (int) (Math.random() * 256);
          int blue = (int) (Math.random() * 256);
          Color color1 = new Color(red, green, blue);
          red = (int) (Math.random() * 256);
          green = (int) (Math.random() * 256);
          blue = (int) (Math.random() * 256);
          Color color2 = new Color(red, green, blue);
    
          gradientPaint = new GradientPaint(0, 0, color1, 20, 20, color2, true);
    
          JLabel promptLabel = new JLabel("Input:");
          promptLabel.setFont(PROMPT_FONT);
          add(promptLabel);
          add(textField);
       }
    
       @Override
       protected void paintComponent(Graphics g) {
          super.paintComponent(g);
          Graphics2D g2 = (Graphics2D) g;
          g2.setPaint(gradientPaint);
          g.fillRect(0, 0, getWidth(), getHeight());
          g.setColor(Color.black);
          g.setFont(PROMPT_FONT);
          g.drawString("Arvaa sana", 100, 100);
       }
    
       @Override
       public Dimension getPreferredSize() {
          if (isPreferredSizeSet()) {
             return super.getPreferredSize();
          }
          return new Dimension(PREF_W, PREF_H);
       }
    
       private static void createAndShowGui() {
          BackgroundPanel mainPanel = new BackgroundPanel();
    
          JFrame frame = new JFrame("BackgroundPanel");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.getContentPane().add(mainPanel);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    

    【讨论】:

    • 正如我所说,我对 java 编程很陌生,并且一直在使用缓冲区策略。也许我错了。必须了解paintComponent 的事情。对不起,愚蠢的问题。
    • @henryheino:请不要误解我的回复——没有人,尤其是我,曾经说过你的问题很愚蠢,因为它不是一个愚蠢的问题。这些类型的渲染用于不同的目的。你画画的目的是什么?复杂的动画?还是更多简单的背景图片?请参阅我的答案的编辑以获取我提到的示例。
    • 在这种情况下,随机单词在屏幕上飞舞。您需要输入它们才能删除。那么,paintCompnent 是否更适合它?
    • 基本上我在arraylist上有整个芬兰语词典。然后程序选择其中的 10 个并在窗口周围飞行。您需要输入该词才能将其从屏幕上删除。
    • 这基本上只是对我的编程培训.. 我得到了屏幕上飞来飞去的话。但后来我被卡住了
    猜你喜欢
    • 1970-01-01
    • 2016-04-29
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 2014-08-20
    • 1970-01-01
    相关资源
    最近更新 更多