Override Java awt repaint system (or at least make a paint listener)

I'm trying to hook up Java awt to a glfw window. I have a container (no parent) with some children, like a button. I want to know when the container is trying to repaint an area, then make my own repainting system that sends the painted content to a texture to be rendered. How can I do this? I've tried overriding repaint and paint in the container, and they don't get called. I don't want to have to insert code for all components that I add to the container. Is there some paint listener thingy I can use to do this? Also, kinda related question. If the container is trying to paint a specific section, I create a BufferedImage, create a graphics for it, then tell the container to paint to it, right? But it would just paint the whole window to that image, but I only want that specific section. And is there a better way than the BufferedImage? I need the output to eventually go to a ByteBuffer. Hope this is clear enough
64 Replies
JavaBot
JavaBot2mo ago
This post has been reserved for your question.
Hey @The Typhothanian! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically marked as dormant after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
dan1st
dan1st2mo ago
If you want to make a UI component with custom things, I think you can extend JPanel (or similar) and extend paintComponent (or whatever that was called) For the second question: If you want to paint to a component, you can use the Graphics/Graphics2D object directly, you don't need to use a BufferedImage if you want to save it to a PNG/JPEG or whatever they you need it
The Typhothanian
The TyphothanianOP2mo ago
yeah looks like I didn't do a good job of explaining. Say I have a Button that is a child of my custom Container. The container is my custom window system (via glfw). I want to know when the Button calls repaint(), so that I can handle the painting myself, to the glfw window. I found this method that looks like it's sending the repaint request to the parent awt window:
public void repaint(long tm, int x, int y, int width, int height) {
if (this.peer instanceof LightweightPeer) {
// Needs to be translated to parent coordinates since
// a parent native container provides the actual repaint
// services. Additionally, the request is restricted to
// the bounds of the component.
if (parent != null) {
if (x < 0) {
width += x;
x = 0;
}
if (y < 0) {
height += y;
y = 0;
}

int pwidth = (width > this.width) ? this.width : width;
int pheight = (height > this.height) ? this.height : height;

if (pwidth <= 0 || pheight <= 0) {
return;
}

int px = this.x + x;
int py = this.y + y;
parent.repaint(tm, px, py, pwidth, pheight);
}
} else {
if (isVisible() && (this.peer != null) &&
(width > 0) && (height > 0)) {
PaintEvent e = new PaintEvent(this, PaintEvent.UPDATE,
new Rectangle(x, y, width, height));
SunToolkit.postEvent(SunToolkit.targetToAppContext(this), e);
}
}
}
public void repaint(long tm, int x, int y, int width, int height) {
if (this.peer instanceof LightweightPeer) {
// Needs to be translated to parent coordinates since
// a parent native container provides the actual repaint
// services. Additionally, the request is restricted to
// the bounds of the component.
if (parent != null) {
if (x < 0) {
width += x;
x = 0;
}
if (y < 0) {
height += y;
y = 0;
}

int pwidth = (width > this.width) ? this.width : width;
int pheight = (height > this.height) ? this.height : height;

if (pwidth <= 0 || pheight <= 0) {
return;
}

int px = this.x + x;
int py = this.y + y;
parent.repaint(tm, px, py, pwidth, pheight);
}
} else {
if (isVisible() && (this.peer != null) &&
(width > 0) && (height > 0)) {
PaintEvent e = new PaintEvent(this, PaintEvent.UPDATE,
new Rectangle(x, y, width, height));
SunToolkit.postEvent(SunToolkit.targetToAppContext(this), e);
}
}
}
but I can't figure out how to intercept the repaint request (including bounds)
dan1st
dan1st2mo ago
Doesn't the button repaint just get called when your repaint is called?
The Typhothanian
The TyphothanianOP2mo ago
uh yeah
dan1st
dan1st2mo ago
Also I think you might be able to extend JButton
The Typhothanian
The TyphothanianOP2mo ago
well I don't really want to have to modify all components for use with this system, and that would get really annoying with complex components with a lot of subcomponents
dan1st
dan1st2mo ago
Also I think you should probably override paintComponent instead of repaint()
The Typhothanian
The TyphothanianOP2mo ago
wdym it wouldn't get called because there isn't an awt window
dan1st
dan1st2mo ago
What wouldn't be called?
The Typhothanian
The TyphothanianOP2mo ago
the paint methods
dan1st
dan1st2mo ago
not?
The Typhothanian
The TyphothanianOP2mo ago
I've checked cus there isn't a graphics for it to be called on
dan1st
dan1st2mo ago
You are dealing with Swing, right?
The Typhothanian
The TyphothanianOP2mo ago
kinda I'm making a game with lwjgl, and want to hook up java awt to the glfw window so I don't have to make a whole component system myself already got most of the stuff done like input and such I just need to know when a child of the window needs to repaint, then handle that myself, because a glfw window isn't an awt window and it wouldn't get handled for the ui if you want I can share my code
dan1st
dan1st2mo ago
Just repaint the subcomponent when you are asked to repaint?
The Typhothanian
The TyphothanianOP2mo ago
uhhhhhhhh huh what Sorry, getting really confused on what you are saying. The child (say, a button) calls repaint() when it needs to repaint, then weird java voodoo magic tells the AWT window to repaint that area. It doesn't go through the component tree until it gets to the window, so I can't override my custom glfw window container's repaint method to paint to the glfw window
dan1st
dan1st2mo ago
Why does the button call repaint?
The Typhothanian
The TyphothanianOP2mo ago
like when the mouse moves over it or something
dan1st
dan1st2mo ago
Can't you extend the button class and override repaint?
The Typhothanian
The TyphothanianOP2mo ago
yeah I could but I'd have to do that for every single component, which I don't feel like doing
dan1st
dan1st2mo ago
Do you have many different component types?
dan1st
dan1st2mo ago
Container (Java SE 21 & JDK 21)
declaration: module: java.desktop, package: java.awt, class: Container
dan1st
dan1st2mo ago
I'm not sure what exactly that does though
The Typhothanian
The TyphothanianOP2mo ago
that's for adding and removal of comps
dan1st
dan1st2mo ago
How many different types of containers do you have?
The Typhothanian
The TyphothanianOP2mo ago
well currently I have a Container that's acting as the window and a JButton as a child of the container, and I'm testing calling repaint() on the button but that's just for testing there's gonna be a lot more for my actual game
dan1st
dan1st2mo ago
With extending, you'd only have to extend JButton that way
The Typhothanian
The TyphothanianOP2mo ago
mmmm yeah that's just for testing part
dan1st
dan1st2mo ago
btw BufferedImage will likely be slow
The Typhothanian
The TyphothanianOP2mo ago
I'd have a whole slew of other stuff I'd need to override well I need to get a Graphics to an opengl texture
dan1st
dan1st2mo ago
Aren't there lwjgl components you can use instead of Swing?
The Typhothanian
The TyphothanianOP2mo ago
I'm planning on making a ByteBuffer that stays between frames, then when a section needs repainting I create a BufferedImage that size, get graphics, paint comp to graphics, put the img content in the byte buf at appropriate area, and upload byte buf to texture again uh no no one really does what I'm attempting worst case I could make a whole new component system but that would take a long while
dan1st
dan1st2mo ago
What do you need the components for? Why?
The Typhothanian
The TyphothanianOP2mo ago
like buttons for my game's ui, hotbar, inventory, stuff like that because I need to render the content to the window with opengl
dan1st
dan1st2mo ago
if you draw to a BufferedImage, that might take longer than you are suppsed to draw
The Typhothanian
The TyphothanianOP2mo ago
is there a better alternative? I eventually need to move the content to a byte buffer if I was coding in C++ there would be a much better way, but I like Java more
dan1st
dan1st2mo ago
Why? Why put it in a ByteBuffer?
The Typhothanian
The TyphothanianOP2mo ago
to upload to the opengl texture to send to the gpu to render each frame on top of game content the texture only takes byte buf for the texture pixels
dan1st
dan1st2mo ago
Isn't lwjgl supposed to do that for you?
The Typhothanian
The TyphothanianOP2mo ago
what part
dan1st
dan1st2mo ago
Are you doing that each frame?
The Typhothanian
The TyphothanianOP2mo ago
no only when the awt needs to redraw
dan1st
dan1st2mo ago
putting it to the GPU
The Typhothanian
The TyphothanianOP2mo ago
and I need to figure out how to tell when it needs to redraw yeah it does do that for you I just have to tell it what to put in the texture (texture covers whole window btw)
dan1st
dan1st2mo ago
When does a button need to repainted without you being informed?
The Typhothanian
The TyphothanianOP2mo ago
wdym
dan1st
dan1st2mo ago
You wanted to get called when the button needs repainting But why is that happening without you getting informed?
The Typhothanian
The TyphothanianOP2mo ago
yeah, code to actually paint the button cus that isn't happening because java awt isn't meant to be hacked like this, usually it handles the window itself including repainting so I might just have to remake a component system, ugh
dan1st
dan1st2mo ago
yes but AWT/Swing shouldn't randomly randomly call repaint on buttons
The Typhothanian
The TyphothanianOP2mo ago
it... isn't if I move my mouse over the button or click it or something, it needs to repaint the issue I have is that there isn't a system that I can find that can redirect repaint calls to my code
dan1st
dan1st2mo ago
Can you capture mouse move events?
The Typhothanian
The TyphothanianOP2mo ago
yes I've already done that easily
dan1st
dan1st2mo ago
then just do the repainting whenever you have anything happening that would need to repaint it
The Typhothanian
The TyphothanianOP2mo ago
well again I'd have to do that for every component I plan on adding
dan1st
dan1st2mo ago
If if you only have a few component types, extending shouldn't be a lot of work
The Typhothanian
The TyphothanianOP2mo ago
I think I should just create a new component system well I don't
dan1st
dan1st2mo ago
you can do it with composition maybe
The Typhothanian
The TyphothanianOP2mo ago
composition?
dan1st
dan1st2mo ago
public class WrapperComponent extends Component{
private Component target;
//for every relevant methods, delegate
@Override
public void repaint(Graphics graphics){

//in the case of repaint, you call your custom code
hereYouKnowItsRepainted();

target.repaint(target);
}
}
public class WrapperComponent extends Component{
private Component target;
//for every relevant methods, delegate
@Override
public void repaint(Graphics graphics){

//in the case of repaint, you call your custom code
hereYouKnowItsRepainted();

target.repaint(target);
}
}
The Typhothanian
The TyphothanianOP2mo ago
but when the target calls repaint internally it won't call the wrapper repaint
dan1st
dan1st2mo ago
You can't do anything against it except extending or also call your repaint method in all of the relevant methods
The Typhothanian
The TyphothanianOP2mo ago
mmmmmkay guess I'm gonna make a custom component system
JavaBot
JavaBot2mo ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
Want results from more Discord servers?
Add your server