GBUI: Componet that allows editing multiple text lines

Hello, All !



Is there a component like BTextField in GBUI that allows to display and edit multiple lines of text?



Or is it planned to write one?

Take a look at this thread:

http://www.jmonkeyengine.com/forum/index.php?topic=7753.15



Standtrooper is often busy with (other) work and it seems he is the only active developer at the moment, so progress is a bit slow. I’m hoping to be able to add some things to gbui soon(ish), but I haven’t looked closely into it yet, so I’m not quite sure how everything works, especially the Lines and Runs.



Oh, Standtrooper, if you read this, do you know if there’s a bug with BScrollingList with BContainer?

I was trying to make a tabbed window (using containers to hold each “page”) but the BScrollingList wouldn’t play with the BContainer, I had to put it in the window directly. If I put it in the BContainer, it would flicker.

I'm not the only active developer, just the lead and project manager.  The editor pane has been a pain in my butt for a year now.  It seems that when I get time to work on it, that time is ripped away from me.  I've started looking at this again to see if I can get it done here in the next few weeks (as I have some time, but not a lot.)



BScrollingList extends BContainer - I'm sure that adding a BContainer to another BContainer might cause a flicker by trying to render both BContainers at the same time - lemmie look at this and see if I can recreate your issue and come up with a workaround if I can recreate it.

@Tumaini i don't know what issues you were seeing, i couldn't recreate it.



What I did do is put the component on a container which just needs to be accomplished with a layoutmanager



Here is the modified createWindows method in ScrollingListTest - hope this helps


        final BWindow window = new BDecoratedWindow(BuiSystem.getStyle(), null);

        window.setLayoutManager(GroupLayout.makeVStretch());

        final BScrollingList<String, BButton> list =
                new BScrollingList<String, BButton>() {
                    @Override
                    public BButton createComponent(String str) {
                        return new BButton(str);
                    }
                };

        for (int i = 0; i < 100; i++) {
            list.addValue("Item #" + i, true);
        }

        BContainer bc = new BContainer();
        bc.setLayoutManager(new BorderLayout());
        bc.add(list, BorderLayout.SOUTH);
        bc.add(new BLabel("bob2"), BorderLayout.NORTH);

        window.add(bc);

        BuiSystem.getRootNode().addWindow(window);
        window.setSize(400, 400);
        window.setLocation(25, 25);

Thanks, Standtrooper!

I’m glad to hear there are other active developers working on gbui as well.



Actually, when using the above code in ScrollingListTest I get a strange problem.

When it starts, the label with title bob2 is north as expected, but the scrolling list is at the bottom showing only a few BButtons. This is not too unexpected either, as it’s being placed south, but when you try to scroll up and move your mouse over the upwards arrow, the list increases in size upwards until the scrollbar to the right reaches the bottom of it’s area.

Setting the preferredSize for the list seems to solve this, though it only uses the height and ignores the width.



In my own example, it’s now working to put a BScrollingList in a BContainer, so I’m not sure what I did to make it flicker before. Sorry about that.

I was wondering though, have you or any other developer done any work on resizable windows?

I was thinking I would do resizable windows with 9 containers, so you could resize in all directions and have the content in the middle, but if someone has already worked on this, they might have a better idea or an already working solution?

I guess it would extend BDraggableWindow, since you would usually want the resizable windows to also be draggable.

If it’s of any interest, I could submit code for tabs in windows as well, as I think I will be working on that anyway.



Edit: Sorry to be asking so much, but how come the BTitledWindow variables originalBounds, maximizedBounds and previousState are private? I had to change them to protected to be able to make use of them in an extension of BTitledWindow. Also, why no getters of titleBar and statusBar?

I know you didn’t code this entire library, so maybe you didn’t see this yet, but perhaps these changes wouldn’t hurt? :slight_smile:



Edit2: Here is a first version of BTabbedPane that I finished today.

See if you like it or if you think something needs to be changed.

Perhaps it’s too implementation specific, but here’s the code for the four classes anyway.



Edit3: Actually, I found there was already a BTabbedPane (funny how I chose the exact same name!) in gbui, I just didn’t see it before. This works for my uses I think and it seems to be extendable as well.



Edit4: I found now that I can add a BScrollingList to a BContainer with a BorderLayout, but not to a BContainer with GroupLayout.makeVert and not to a BContainer with a BorderLayout that is itself a child of a BContainer with GroupLayout.makeVert.

Sorry for using this thread as a dumping area for my implementation ideas. :stuck_out_tongue:

I just don't know where else to put them, as I don't know of any gbui forum.



Anyway, I was having trouble before with changing the colour of text and had to use very cumbersome methods, like removing the label, creating a new one with a different style class (only difference is colour) and then adding this in the same place as the removed one. So I thought I'd at least test to see if it would be possible to set the colour after adding the component to the scene. It worked splendidly!

Now, I don't know all the inner workings of BComponents, so I don't know if it might cause any errors in certain cases that I haven't tested for, but here is the patch for BComponent to add two methods:

*setColor(ColorRGBA color, int state) to set the colour for a certain state (default, hover…)

*setColor(ColorRGBA color) to set the same colour for all states


Index: src/java/com/jmex/bui/BComponent.java
===================================================================
--- src/java/com/jmex/bui/BComponent.java   (revision 336)
+++ src/java/com/jmex/bui/BComponent.java   (working copy)
@@ -276,6 +276,18 @@
         Insets insets = _insets[getState()];
         return (insets == null) ? Insets.ZERO_INSETS : insets;
     }
+    
+    public void setColor(ColorRGBA color, int state) {
+       _colors[state] = color;
+       invalidate();
+    }
+    
+    public void setColor(ColorRGBA color) {
+       for(int i=0; i<STATE_COUNT; i++) {
+          _colors[i] = color;
+       }
+       invalidate();
+    }
 
     /**
      * Returns the (foreground) color configured for this component.



Here is a test class that tests BLabel, BTextField, disabled BTextField, BTextArea and BButton.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.Callable;

import javax.swing.Timer;

import com.jme.app.SimpleGame;
import com.jme.input.InputHandler;
import com.jme.input.MouseInput;
import com.jme.renderer.ColorRGBA;
import com.jme.util.GameTaskQueueManager;
import com.jmex.bui.BButton;
import com.jmex.bui.BComponent;
import com.jmex.bui.BLabel;
import com.jmex.bui.BTextArea;
import com.jmex.bui.BTextField;
import com.jmex.bui.BuiSystem;
import com.jmex.bui.PolledRootNode;
import com.jmex.bui.headlessWindows.BDraggableWindow;
import com.jmex.bui.layout.GroupLayout;
import com.jmex.bui.layout.Justification;

public class ColorTest extends SimpleGame {
   public ColorTest() {
      
   }
   
   public static void main(String[] args) {
      ColorTest test = new ColorTest();
      test.start();
   }

   @Override
   protected void simpleInitGame() {
      BuiSystem.init(new PolledRootNode(com.jme.util.Timer.getTimer(), new InputHandler()), "/test/mainGui.bss");
        rootNode.attachChild(BuiSystem.getRootNode());
        
        MouseInput.get().setCursorVisible(true);
        
        BDraggableWindow window = new BDraggableWindow(BuiSystem.getStyle(), GroupLayout.makeVert(Justification.TOP));
        window.setSize(settings.getWidth()/2, settings.getHeight()/2);
        window.setLocation(settings.getWidth()/2-window.getWidth()/2, settings.getHeight()/2-window.getHeight()/2);
        BuiSystem.addWindow(window);
        
        final BLabel label = new BLabel("Text");
        window.add(label);
        final BTextField field = new BTextField("TextField");
        field.setPreferredSize(100, 25);
        window.add(field);
        final BTextField field2 = new BTextField("TextField2");
        window.add(field2);
        field2.setEnabled(false);
        final BTextArea area = new BTextArea("Textnonnseveralnlines");
        window.add(area);
        final BButton button = new BButton("Button");
        window.add(button);
        
        Timer timer = new Timer(3000, new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            GameTaskQueueManager.getManager().update(new Callable<Object>() {
               @Override
               public Object call() throws Exception {
                  label.setColor(ColorRGBA.green.clone());
                  field.setColor(ColorRGBA.cyan.clone(), BComponent.DEFAULT);
                  field2.setColor(ColorRGBA.yellow.clone(), BComponent.DISABLED);
                  area.setColor(new ColorRGBA(0.4f, 1f, 0.4f, 0.7f));
                  button.setColor(ColorRGBA.orange, BComponent.HOVER);
                  button.setColor(ColorRGBA.black, BButton.DOWN);
                  return null;
               }
            });
         }
        });
        timer.start();
   }
}


It seems to work and it's extremely helpful to be able to change such a basic thing as the foreground colour. You can already change the background. Let me know what you think and also if there is a better place to post these kinds of things!

EDIT: A question: Is there a preferred way to get the window that I click on to go to the top layer?
I'm using the following now (extending BTitledWindow or other windows), but perhaps there is already a standard way to do it?

public boolean dispatchEvent(final BEvent event) {
        if (event instanceof MouseEvent) {
            MouseEvent mev = (MouseEvent) event;
            switch (mev.getType()) {
                case MouseEvent.MOUSE_PRESSED:
                    if (mev.getButton() == 0) {
                        requestFocus();
                    }
                    break;
            }
        }

        return super.dispatchEvent(event);
    }
   
   public void requestFocus() {
      for(BWindow win : BuiSystem.getRootNode().getAllWindows()) {
         if(win.getLayer() > 0) {
            win.setLayer(0);
         }
      }
      setLayer(1);
   }