覆盖绘图(图形g)Java

时间:2015-09-24 01:18:28

标签: java swing paint paintcomponent undo

我在NetBeans中的GUI有一点问题。当用户在鼠标位置的JPanel中进行陈词滥调时,我会绘制图像(点)。这部分工作正常。我将每个图像位置存储在两个不同的ArrayList中,该ArrayList包含X位置和Y位置。现在我要做的是在单击按钮后删除Panel中绘制的最新图像。所以我做的是删除两个ArrayList的最后一个索引,然后调用repaint()从X和Y ArrayList中的位置绘制所有图像(下面的代码)。

奇怪的是,我需要调整GUI的大小(将其全屏显示或仅更改其大小),以便在JPanel中再次显示绘制的图像,否则面板将保持空白。 / p>

以下是受影响的代码部分:

public void paint(Graphics g) {

    super.paint(g);
    for(int i=0;i<=listePointsX.size()-1;i++) {
        try{
            BufferedImage icon = ImageIO.read(getClass().getResourceAsStream("/myimage.png"));
            Graphics graphe = jPanel1.getGraphics();
            graphe.setColor(Color.BLACK);
            graphe.drawImage(icon, this.listePointsX.get(i),this.listePointsY.get(i), rootPane);
        }catch(Exception e1){

        }
    }

private void jButtonUndoActionPerformed(java.awt.event.ActionEvent evt) {                                            
    if(listePointsX.size()>0){
        int lastObject= listePointsX.size();
        listePointsX.remove(lastObject-1);
        listePointsY.remove(lastObject-1);
        jPanel1.repaint();         
    }
    else{

    }


}   

任何想法我需要做些什么&#34;刷新&#34;整个东西?难道我做错了什么?尝试搜索但没有找到任何...

2 个答案:

答案 0 :(得分:3)

#include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> bool writeDataToClient(int sckt, const void *data, int datalen) { const char *pdata = (const char*) data; while (datalen > 0){ int numSent = send(sckt, pdata, datalen, 0); if (numSent <= 0){ if (numSent == 0){ printf("The client was not written to: disconnected\n"); } else { perror("The client was not written to"); } return false; } pdata += numSent; datalen -= numSent; } return true; } bool writeStrToClient(int sckt, const char *str) { return writeDataToClient(sckt, str, strlen(str)); } int main(void){ int create_socket, new_socket; char *buffer; int bufsize = 1024; struct sockaddr_in address; socklen_t addrlen; buffer = (char*) malloc(bufsize); if (!buffer){ printf("The receive buffer was not allocated\n"); exit(1); } create_socket = socket(AF_INET, SOCK_STREAM, 0); if (create_socket == -1){ perror("The socket was not created"); exit(1); } printf("The socket was created\n"); memset(&address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(80); if (bind(create_socket, (struct sockaddr *) &address, sizeof(address)) == -1){ perror("The socket was not bound"); exit(1); } printf("The socket is bound\n"); long fsize; FILE *fp = fopen("index.html", "rb"); if (!fp){ perror("The file was not opened"); exit(1); } printf("The file was opened\n"); if (fseek(fp, 0, SEEK_END) == -1){ perror("The file was not seeked"); exit(1); } fsize = ftell(fp); if (fsize == -1) { perror("The file size was not retrieved"); exit(1); } rewind(fp); char *msg = (char*) malloc(fsize); if (!msg){ perror("The file buffer was not allocated\n"); exit(1); } if (fread(msg, fsize, 1, fp) != 1){ perror("The file was not read\n"); exit(1); } fclose(fp); printf("The file size is %ld\n", fsize); if (listen(create_socket, 10) == -1){ perror("The socket was not opened for listening"); exit(1); } printf("The socket is listening\n"); while (1) { addrlen = sizeof(address); new_socket = accept(create_socket, (struct sockaddr *) &address, &addrlen); if (new_socket == -1) { perror("A client was not accepted"); exit(1); } printf("A client is connected from %s:%hu...\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port)); // I will leave it as an exercise for you to implement // a proper HTTP request parser here... int numRead = recv(new_socket, buffer, bufsize, 0); if (numRead < 1){ if (numRead == 0){ printf("The client was not read from: disconnected\n"); } else { perror("The client was not read from"); } close(new_socket); continue; } printf("%.*s\n", numRead, buffer); if (!writeStrToClient(new_socket, "HTTP/1.1 200 OK\r\n")){ close(new_socket); continue; } char clen[40]; sprintf(clen, "Content-length: %ld\r\n", fsize); if (!writeStrToClient(new_socket, clen)){ close(new_socket); continue; } if (!writeStrToClient(new_socket, "Content-Type: text/html\r\n")){ close(new_socket); continue; } if (!writeStrToClient(new_socket, "Connection: close\r\n\r\n") == -1){ close(new_socket); continue; } //if (!writeStrToClient(new_socket, "<html><body><H1>Hello world</H1></body></html>")){ if (!writeDataToClient(new_socket, msg, fsize)){ close(new_socket); continue; } printf("The file was sent successfully\n"); close(new_socket); } close(create_socket); return 0; } 不是绘画应该如何工作,相反,你应该覆盖面板的Graphics graphe = jPanel1.getGraphics();方法并在其中绘制点。

有关绘画如何在Swing

中工作的详细信息,请参阅Painting in AWT and SwingPerforming Custom Painting

相反,您的小组应该完成所有工作,管理paintComponent中的点并绘制它们。您的父组件“可能”能够在符合您的设计要求的情况下添加或删除积分,但核心职责仍由小组负责。

避免在ArrayList方法中执行任何长时间运行或阻止操作,它们应尽可能快地运行。由于图像永远不会改变,您只需加载一次(无论是在构造类时还是在第一次需要图像时)并继续使用相同的引用。

答案 1 :(得分:1)

好吧现在工作得很好。我必须像你告诉我的那样去做。我创建了一个扩展jPanel的新类(下面)。然后在我的主窗体中,不得不创建这个类的对象。每当用户单击时,它将调用此Drawing类对象并将项添加到ArrayList(此对象管理有关创建的点的所有内容......它看起来像这样:

public class MyDrawingClass extends JPanel {
ArrayList<Integer> arrayListPointX = new ArrayList<>();
ArrayList<Integer> arrayListPointY = new ArrayList<>();

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    try{
    BufferedImage icon = ImageIO.read(getClass().getResourceAsStream("/images/dot.png"));
    g.setColor(Color.BLACK);
    if(arrayListPointX.size()<=0){
        ...
    }
    else{
        for(int i=0;i<listePointsX.size();i++){
                g.setColor(Color.BLACK);
                g.drawImage(icon, listePointsX.get(i), listePointsY.get(i), rootPane);
        }
    }
    }catch(Exception e){
        ...
    }
}

因此,如果我想&#34;撤消&#34;,请说出我的对象&#34; MyDrawingClass&#34;被称为&#34; draw&#34;。我可以这样做:draw.arrayListPointX.remove(draw.arrayListPointX.size() - 1);并调用repaint();显示剩余的点数。

感谢您的提示欣赏它! :)