我在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;整个东西?难道我做错了什么?尝试搜索但没有找到任何...
答案 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 Swing和Performing 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();显示剩余的点数。
感谢您的提示欣赏它! :)