我有一个大问题无法解决——我在JFrame
中有一个JPanel
。在这个面板中,我画了很多东西(比如图表),它是有效的,但当我滚动面板或调整框架大小时,图形就会消失!
我应该如何保留这幅画?
代码:
private void full_simulation_button(java.awt.event.ActionEvent evt) {
if (jTextField1.getText().equals("")){
JOptionPane jop2 = new JOptionPane();
jop2.showMessageDialog(null, "You should enter you trace file !", "Attention", JOptionPane.WARNING_MESSAGE);
}
else {
Graphics g = jPanel5.getGraphics();
g.setColor(Color.RED);
g.drawRect(150,10,100,20);
g.fillRect(150,10,100,20);
g.drawLine(200,10 , 200, 2000);
g.setColor(Color.BLACK);
g.drawString("UE",190 ,25 );
g.setColor(Color.BLUE);
g.drawRect(350,10,100,20);
g.fillRect(350,10,100,20);
g.drawLine(400,10 , 400, 2000);
g.setColor(Color.BLACK);
g.drawString("Node B",380 ,25 );
g.setColor(Color.GREEN);
g.drawRect(550,10,100,20);
g.fillRect(550,10,100,20);
g.drawLine(600,10 , 600, 2000);
g.setColor(Color.BLACK);
g.drawString("RNC",590 ,25 );
g.setColor(Color.YELLOW);
g.drawRect(750,10,100,20);
g.fillRect(750,10,100,20);
g.drawLine(800,10 , 800, 2000);
g.setColor(Color.BLACK);
g.drawString("CN",790 ,25 );
System.out.println(new java.io.File("").getAbsolutePath());
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
final DocumentBuilder builder = factory.newDocumentBuilder();
final Document document= builder.parse(new File(jTextField1.getText()));
//Affiche la version de XML
System.out.println("la version du XML est "+ document.getXmlVersion());
//Affiche l'encodage
System.out.println("l'encodage utilisé est"+document.getXmlEncoding());
//Affiche s'il s'agit d'un document standalone
System.out.println("le document est standolone:"+document.getXmlStandalone());
final Element racine = document.getDocumentElement();
System.out.println("le racime du fichier est :"+racine.getNodeName());
final NodeList racineNoeuds = racine.getChildNodes();
final int nbRacineNoeuds = racineNoeuds.getLength();
for (int i = 0; i<nbRacineNoeuds; i++) {
if(racineNoeuds.item(i).getNodeType() == Node.ELEMENT_NODE) {
final Element nd = (Element) racineNoeuds.item(i);
final Node noeud = racineNoeuds.item(i);
System.out.println(noeud.getNodeName());
final NodeList msg = nd.getElementsByTagName("PARA");
final int nbre = msg.getLength();
int marge=0;
int rang =1;
String type =null;
String direction=null;
for(int j = 0; j<nbre ; j++){
final Element message = (Element) msg.item(j);
g.setColor(Color.BLACK);
if ( message.getAttribute("name").equals("Message Type")){
type = message.getAttribute("value");
// System.out.println(type);
if (type.startsWith("RRC")){
g.drawLine(200,50+marge , 600, 50+marge);
g.drawString(rang+". "+type,220 ,45+marge );
marge=marge+30;
rang=rang+1;
}
if (type.startsWith("NBAP")){
g.drawLine(400,50+marge , 600, 50+marge);
g.drawString(rang+". "+type,420 ,45+marge );
marge=marge+30;
rang=rang+1;
}
if (type.startsWith("RANAP")){
g.drawLine(600,50+marge , 800, 50+marge);
g.drawString(rang+". "+type,620 ,45+marge );
marge=marge+30;
rang=rang+1;
}
}
if ( message.getAttribute("name").equals("Message Direction")){
direction = message.getAttribute("value");
//System.out.println(direction);
if ((direction.equals("From-UE"))&&(type.startsWith("RRC"))){
g.drawString(">",595, 50+marge-25 );
System.out.println(type);
}
if ((direction.equals("To-UE"))&&(type.startsWith("RRC"))){
g.drawString("<",200, 50+marge-25 );
System.out.println(type);
}
if ((direction.equals("From-NodeB"))&&(type.startsWith("NBAP"))){
g.drawString(">",595, 50+marge-25 );
System.out.println(type);
}
if ((direction.equals("To-NodeB"))&&(type.startsWith("NBAP"))){
g.drawString("<",400, 50+marge-25 );
System.out.println(type);
}
if ((direction.equals("From-CN"))&&(type.startsWith("RANAP"))){
g.drawString("<",600, 50+marge-25 );
System.out.println(type);
}
if ((direction.equals("To-CN"))&&(type.startsWith("RANAP"))){
g.drawString(">",795, 50+marge-25 );
System.out.println(type);
}
}
}
}
}
}
catch (final ParserConfigurationException e) {
e.printStackTrace();
}
catch (final SAXException e) {
e.printStackTrace();
}
catch (final IOException e) {
e.printStackTrace();
}
}
}
您不应该在所提供的swing函数(如paintComponent(Graphics g)
)之外进行绘制。调整大小或滚动时,将重新绘制组件。在这个过程中,调用每个相关组件的paintComponent
方法。由于绘图发生在面板外部,因此不会按预期重新绘制面板。覆盖paintComponent
方法并将所有绘图代码复制到其中。
class MyPanel extends JPanel
{
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.RED);
g.drawRect(150,10,100,20);
g.fillRect(150,10,100,20);
g.drawLine(200,10 , 200, 2000);
g.setColor(Color.BLACK);
g.drawString("UE",190 ,25 );
/* ... All drawing code ... */
}
}
每次调整组件大小或在滚动窗格中移动组件时,都会重新绘制。这就是Swing的工作方式。如果您希望面板能够重新绘制其内容,它必须了解它。在这种情况下,应该创建一个扩展JComponent
类并重写paintComponent(Graphics)
方法的新类。正是这种方法将负责绘制您的图表。
public class Drawer extends JComponent {
private File source;
public void setSource(File source) {
this.source = source;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (source == null) {
return;
}
g.setColor(Color.RED);
g.drawRect(150, 10, 100, 20);
g.fillRect(150, 10, 100, 20);
g.drawLine(200, 10, 200, 2000);
g.setColor(Color.BLACK);
g.drawString("UE", 190, 25);
g.setColor(Color.BLUE);
g.drawRect(350, 10, 100, 20);
g.fillRect(350, 10, 100, 20);
g.drawLine(400, 10, 400, 2000);
g.setColor(Color.BLACK);
g.drawString("Node B", 380, 25);
g.setColor(Color.GREEN);
g.drawRect(550, 10, 100, 20);
g.fillRect(550, 10, 100, 20);
g.drawLine(600, 10, 600, 2000);
g.setColor(Color.BLACK);
g.drawString("RNC", 590, 25);
g.setColor(Color.YELLOW);
g.drawRect(750, 10, 100, 20);
g.fillRect(750, 10, 100, 20);
g.drawLine(800, 10, 800, 2000);
g.setColor(Color.BLACK);
g.drawString("CN", 790, 25);
System.out.println(new java.io.File("").getAbsolutePath());
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
final DocumentBuilder builder = factory.newDocumentBuilder();
final Document document = builder.parse(source);
} catch (final ParserConfigurationException e) {
e.printStackTrace();
} catch (final SAXException e) {
e.printStackTrace();
} catch (final IOException e) {
e.printStackTrace();
}
}
}
用Drawer类的实例替换JPanel,并用替换监听器方法的内容
private void full_simulation_button(java.awt.event.ActionEvent evt) {
if (jTextField1.getText().isEmpty()) {
JOptionPane.showMessageDialog(null, "You should enter you trace file !", "Attention", JOptionPane.WARNING_MESSAGE);
} else {
drawer.setSource(new File(jTextField1.getText()));
}
}
当用户单击按钮时,将创建一个文件,并将其作为Drawer
的源。Drawer
重新绘制自己,paintComponent()
方法由Swing的内部机制调用。
现在,您应该尝试通过不在每次调用paintComponent()
方法时解析XML文件来改进代码(在setSource()
中解析它,然后在paintComponent()
中使用数据)。