How can insert a jlabel inside a jdesktop pane in netbeans. When i tried to drag and drop it didn't work? The desktop pane got displaced - netbeans

I also tried to enclose the label inside a dekstop pane. But a message flashed that cannot enclose components in a non-empty container. Any help shall be appreciated

Using Netbeans 11.0 I was able to drag a JLabel into a JDesktopPane and I did not see the error you reported. However I believe that JDesktopPane was designed just to be a container for JInternalFrames rather than having other components embedded directly. This was for MDI applications that aren't seen so much these days.
Have a look at the relevant Swing Tutorial for background info.
I have also put a minimal example here which you can paste into an empty class in Netbeans
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JDesktopPane desktop_pane = new JDesktopPane();
frame.getContentPane().add(desktop_pane);
for (int i = 1; i <= 5; ++i) {
JInternalFrame internal = new JInternalFrame(String.format("Window %d", i), true, true, true, true);
internal.setSize(150, 80);
internal.setLocation(i * 50, i * 50);
internal.setVisible(true);
desktop_pane.add(internal);
}
desktop_pane.setPreferredSize(new Dimension(800, 600));
frame.pack();
SwingUtilities.invokeLater(() -> {
frame.setVisible(true);
});
}
It will create a desktop with five resizeable windows in it.

Related

Why is draw_picture called so many times?

When I run the following programme:
//compile: valac --pkg gtk+-3.0 sample.vala
using Gtk;
public class Main : Object
{
private Window window;
private Gdk.Pixbuf pixbuf;
private DrawingArea da1;
public Main()
{
window = new Window();
window.destroy.connect (main_quit);
pixbuf = new Gdk.Pixbuf.from_file("sample.jpg");
var box = new Box (Orientation.VERTICAL, 5);
da1 = new DrawingArea();
da1.set_hexpand(true);
da1.set_vexpand(true);
da1.draw.connect((context) => draw_picture(context, pixbuf));
box.pack_start (da1, true, true, 0);
window.add (box);
window.show_all();
}
bool draw_picture(Cairo.Context cr, Gdk.Pixbuf pixbuf)
{
print("draw_picture\n");
int width = da1.get_allocated_width();
int height = da1.get_allocated_height();
var temp = pixbuf.scale_simple(width, height, Gdk.InterpType.BILINEAR);
Gdk.cairo_set_source_pixbuf (cr, temp, 0, 0);
cr.paint ();
return false;
}
static int main(string[] args)
{
Gtk.init(ref args);
var app = new Main();
Gtk.main();
return 0;
}
}
after start I can see 'draw_picture' printed 2 times. When I switch window to terminal, it's displayed additional 7 times. Can anyone explain why and recommend some good book explaining the details?
In order to answer that question for sure, you would need to look at how your window manager works. Probably the redraws that occur when you switch to another window are due to the widget gaining the :backdrop pseudoclass when its window ceases to be the active window.
In general a widget's draw signal is invoked whenever the window manager needs to redraw a portion of the window that includes the widget, and also whenever the widget's active style changes.
If your widget is expensive to redraw then you can avoid drawing the whole thing when it's not necessary. The Cairo context's clip region will be set to the portion which needs redrawing.

Gtk - draw event fired for wrong widget, and widget not redrawn

I'm trying to create a custom scrollable text area. I created a DrawingArea and a ScrollBar inside a Grid. I have attached the draw event of DrawingArea to this.on_draw method which simply looks at ScrollBar's value and moves the Cairo.Context appropriately before drawing the Pango.Layout.
The first problem is that this.on_draw is getting invoked whenever the ScrollBar is touched even though I have not registered any events with ScrollBar. How do I prevent this, or check this?
The second problem is that even though this.on_draw is invoked, the changes made to the Context is not displayed unless the ScrollBar value is near 0 or 100 (100 is the upper value of Adjustment). Why is this happening?
I did find out that if I connect the value_changed event of ScrollBar to a method that calls queue_redraw of DrawingArea, it would invoke this.on_draw and display it properly after it. But due to the second problem, I think this.on_draw is getting invoked too many times unnecessarily. So, what is the "proper" way of accomplishing this?
using Cairo;
using Gdk;
using Gtk;
using Pango;
public class Texter : Gtk.Window {
private Gtk.DrawingArea darea;
private Gtk.Scrollbar scroll;
private string text = "Hello\nWorld!";
public Texter () {
GLib.Object (type: Gtk.WindowType.TOPLEVEL);
Gtk.Grid grid = new Gtk.Grid();
this.add (grid);
var drawing_area = new Gtk.DrawingArea ();
drawing_area.set_size_request (200, 200);
drawing_area.expand = true;
drawing_area.draw.connect (this.on_draw);
grid.attach (drawing_area, 0, 0);
var scrollbar = new Gtk.Scrollbar (Gtk.Orientation.VERTICAL,
new Gtk.Adjustment(0, 0, 100, 0, 0, 1));
grid.attach (scrollbar, 1, 0);
this.darea = drawing_area;
this.scroll = scrollbar;
this.destroy.connect (Gtk.main_quit);
}
private bool on_draw (Gtk.Widget sender, Cairo.Context ctx) {
ctx.set_source_rgb (0.9, 0.9, 0.9);
ctx.paint ();
var y_offset = this.scroll.get_value();
stdout.printf("%f\n", y_offset);
ctx.set_source_rgb (0.25, 0.25, 0.25);
ctx.move_to(0, 100 - y_offset);
var layout = Pango.cairo_create_layout(ctx);
layout.set_font_description(Pango.FontDescription.from_string("Sans 12"));
layout.set_auto_dir(false);
layout.set_text(this.text, this.text.length);
Pango.cairo_show_layout(ctx, layout);
return false;
}
static int main (string[] args) {
Gtk.init (ref args);
var window = new Texter ();
window.show_all ();
Gtk.main ();
return 0;
}
}
Also, please point out any (possibly unrelated) mistake if you find one in the above code.
The part that you are missing is that a draw signal does not mean "redraw everything". Instead, GTK+ sets the clip region of the cairo context to the part that needs to be redrawn, so everything else you do doesn't have any effect. The cairo function cairo_clip_extents() will tell you what that region is. The queue_draw_area() method on GtkWidget will allow you to explicitly mark a certain area for drawing, instead of the entire widget.
But your approach to scrollbars is wrong anyway: you're trying to build the entire infrastructure from scratch! Consider using a GtkScrolledWindow instead. This automatically takes care of all the details of scrolling for you, and will give you the overlay scrollbars I mentioned. All you need to do is set the size of the GtkDrawingArea to the size you want it to be, and GtkScrolledWindow will do the rest. The best way to do this is to subclass GtkDrawingArea and override the get_preferred_height() and/or get_preferred_width() virtual functions (being sure to set both minimum and natural sizes to the sizes you want for that particular dimension). If you ever need to change this size later, call the queue_resize() method of GtkWidget. (You probably could get away with just using set_size_request(), but what I described is the preferred way of doing this.) Doing this also gives you the advantage of not having to worry about transforming your cairo coordinates; GtkScrolledWindow does this for you.

GTK TextView auto scroll when text is added to text buffer

I am trying to create a very simple log-like GUI application that merely displays text from a log file dynamically and asynchronously. The problem is that when the log file is updated, the text view in the GUI scrolls back up to line 1. Every attempt to fix this has failed and I am wondering if I have stumbled across a bug in GTK. Here is a summary of my code:
using Cairo;
using Gtk;
namespace ServerManager {
public class ServerManager : Window {
public TextView text_view;
public TextIter myIter;
public TextMark myMark;
public async void read_something_async (File file) {
var text = new StringBuilder ();
var dis = new DataInputStream (file.read ());
string line;
while ((line = yield dis.read_line_async (Priority.DEFAULT)) != null) {
text.append (line);
text.append_c('\n');
}
this.text_view.buffer.text = text.str;
text_view.buffer.get_end_iter(out myIter);
text_view.scroll_to_iter(myIter, 0, false, 0, 0);
}
public static int main (string[] args) {
Gtk.init (ref args);
var window = new ServerManager ();
// The read-only TextView
window.text_view = new TextView ();
window.text_view.editable = false;
window.text_view.cursor_visible = false;
window.text_view.wrap_mode = Gtk.WrapMode.WORD;
// Add scrolling functionality to the TextView
var scroll = new ScrolledWindow (null, null);
scroll.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
scroll.add (window.text_view);
// Vbox so that our TextView has someplace to live
var vbox = new Box (Orientation.VERTICAL, 0);
vbox.pack_start (scroll, true, true, 0);
window.add (vbox);
window.set_border_width (12);
window.set_position (Gtk.WindowPosition.CENTER);
window.set_default_size (800, 600);
window.destroy.connect (Gtk.main_quit);
window.show_all ();
File file = File.new_for_path ("/home/user/temp.log");
FileMonitor monitor = file.monitor (FileMonitorFlags.NONE, null);
stdout.printf ("Monitoring: %s\n", file.get_path ());
monitor.changed.connect (() => {
window.read_something_async(file);
});
Gtk.main ();
return 0;
}
}
}
I also tried using TextMarks instead of Iters but that had no affect.
Scroll to 1st row happens because read_something_async() deletes the current contents of the buffer and then writes the new one (this is what setting the text property does). Maybe this is what you want but unless you keep track of the scroll location you will lose it.
The reason your scroll_to_iter() didn't work as expected is probably this:
Note that this function uses the currently-computed height of the lines in the text buffer. Line heights are computed in an idle handler; so this function may not have the desired effect if it’s called before the height computations. To avoid oddness, consider using gtk_text_view_scroll_to_mark() which saves a point to be scrolled to after line validation.
Calling TextView.ScrollToMark() with a "right gravity" TextMark should work for you.

Images getting cut off using Swing

I am writing a tile based platform game. At the moment I am trying to get 400 tiles to display at once. This is my panel. On the top and left sides everything is working great but on the right and bottom sides the images are cut off by a few pixels. Each image is 32*32. All of blocks are initialized. None are null. What is wrong here?
public class Pane extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
Timer timer;
boolean setup = false;
Block[][] blocks;
Level level;
public Pane()
{
level = new Level();
level.Generate();
blocks = level.Parse();
setBackground(Color.WHITE);
timer = new Timer(25, this);
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
for(Block[] b : blocks)
{
for(Block bx : b)
{
// Debug code if(bx.letter.equals("D"))
// Debug codeSystem.out.println(bx.y*32 +" = "+ bx.x*32);
g2d.drawImage(bx.bpic, bx.x*32, bx.y*32, this);
}
}
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}
on the right and bottom sides the images are cut off by a few pixels
If you mean the right and bottom sides of the whole panel (not on the single tiles), than it's probably a LayoutManager related problem. The solution depends on the layout manager you are using for the component your JPanel will be added to.
You could try to specify the minimum/preferred size of your JPanel with:
Pane pane = new Pane();
pane.setPreferredSize(...);
pane.setMinimumSize(...);
In order to specify its minimum dimension accordingly to the size of the generated image (32 * COL , 32 * ROW).
Unfortunately the effectiveness of the setPreferredSize call depends on the layout manager of your Pane parent component.
JComponent can do that basically and can return very easily something as MinimumSize or PreferredSize, valid for majority of standard Swing LayoutManagers, examples here.

implementing jlabel by codes in an automated jFrame in netbeans 6.9

Hi
i'm new with java swing,i try a lot and do a lot of search but in vain.i want to display a jlabel(not by drag n drop but with codes) on an automated jFrame that i have already.well my code for my JLabel is as follows:
private JLabel la=new JLabel("Display label");
codes that i got during my search to dispaly in a jpanel was like follows:
jPanel1.add(jLabel1);
but it does not work.My jPanel1 was built by drag n drop with the name Jpanel1.
i even try this piece of code:
this.add(jLabel1)--
this.getContentPane().add(jLabel1)
but still not working.
Please help me,it must be a simple line of code or i'm missing something somewhere ,please..thank you
This is a simple piece of code obtained from link text
public class HelloWorldFrame extends JFrame {
public static void main(String args[]) {
new HelloWorldFrame();
}
HelloWorldFrame() {
JLabel jlbHelloWorld = new JLabel("Hello World");
add(jlbHelloWorld);
this.setSize(100, 100);
// pack();
setVisible(true);
}
}
What you need to do is to re-set the setVisible property of the parent component to true