【问题标题】:JTextFild Glitched OutJTextField 出现故障
【发布时间】:2016-07-19 06:30:06
【问题描述】:

好的,所以我有一个程序,它在 JPanel 上显示一个字符串,它画出 Ascents 所在的线,它在 Descent 和中间画一条线,在中间画一条线,在四分之一之间。我有一个组合框来更改字符串的字体和大小,我有一个 JTextField 来更改文本本身。我使用 actionListeners 来更新字符串。每当我通过 JTextField 更新字符串的文本时,程序就会出现故障,并在 JFrame 的右上角显示 JTextField 图像的副本。

代码:

package com.Patel.RichClients;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

//a class to demonstrate 
public class StringAscent extends JFrame {
    private static Font font;
    private int fontSize = 50; 
    private StringPanel panel; 
    private JComboBox fontOptions; 
    private JComboBox fontSizeOptions; 
    private JTextField text; 


    // constructor
    public StringAscent() {
    // set the initial font to Times new Roman
    font = new Font("Agency FB", Font.PLAIN, fontSize);
    setVisible(true);
    setSize(520, 170);
    setTitle("String Ascents");
    setLayout(new BorderLayout());

    //set up the components 
    GraphicsEnvironment ge= GraphicsEnvironment.getLocalGraphicsEnvironment();
    String[] fontNames = ge.getAvailableFontFamilyNames();
    fontOptions = new JComboBox(fontNames);
    text = new JTextField(22);
    text.setText("Swing");
    String[] sizeOptions = new String[50];
    for (int i = 0; i < sizeOptions.length; i ++){
        sizeOptions[i] = Integer.toString(i + 1);
    }
    fontSizeOptions = new JComboBox(sizeOptions); 
    panel = new StringPanel();

    //set up actionListeners 
    fontOptions.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
        JComboBox ref = (JComboBox) e.getSource();
        font = new Font(fontNames[ref.getSelectedIndex()], Font.PLAIN, fontSize);
        panel.repaint();
        }    
    });
    fontSizeOptions.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
        JComboBox ref = (JComboBox) e.getSource();
        fontSize = Integer.parseInt(sizeOptions[ref.getSelectedIndex()]);
        font = new Font(font.getName(), Font.PLAIN, fontSize);
        panel.repaint();
        }    
    });
    text.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
        panel.repaint();
        }  

    });

    //add components
    add(panel, BorderLayout.NORTH);
    add(fontOptions, BorderLayout.WEST);
    add(text, BorderLayout.CENTER);
    add(fontSizeOptions, BorderLayout.EAST);
    }


    public static void main(String[] args) {
    Runnable showGui = new Runnable() {
        public void run() {
        StringAscent gui = new StringAscent();
        }
    };
    SwingUtilities.invokeLater(showGui);
    }

    // inner JPanel class
    private class StringPanel extends JPanel {

    // constructor
    public StringPanel() {

    }

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

    public void paintComponent(Graphics g) {
        g.setColor(Color.black);

        // set up the string
        g.setFont(font);
        // FontMetric is an object that holds information relevant to the
        // rendering of the font
        FontMetrics metric = g.getFontMetrics();
        int ascent = metric.getAscent();
        String string = text.getText();
        g.drawString(string, 100, 50);

        int x = 50;
        // draw Ascent line
        g.drawLine(x, 50 - ascent, x + 180, 50 - ascent);

        // draw Ascent/2 line
        g.drawLine(x, 50 - (ascent / 2), x + 180, 50 - (ascent / 2));

        // draw Ascent/4 line
        g.drawLine(x, 50 - (ascent / 4), x + 180, 50 - (ascent / 4));

        // draw baseline line
        g.drawLine(x, 50, x + 180, 50);

        // draw Descent line
        g.drawLine(x, 50 + metric.getDescent(), x + 180, 50 + metric.getDescent());

    }
    }
}

【问题讨论】:

    标签: java swing paintcomponent


    【解决方案1】:

    super.paintComponent(g) 添加到paintComponent 方法的开头

    public void paintComponent(Graphics g) {
        super.paintComponent(g)
        g.setColor(Color.black);
        //...
    

    基本上,paintComponent 的工作之一就是为绘制当前组件准备Graphics 上下文。在 Swing 中,Graphics 是一个共享资源,在绘制时由窗口内的所有组件使用,因此在绘制之前确保正确准备上下文很重要

    查看Performing Custom PaintingPainting in AWT and Swing 了解有关绘画工作原理的更多详细信息

    【讨论】:

    • 哇,我完全忘了这样做。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 2012-12-08
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    相关资源
    最近更新 更多