I have a LWUIT form which contains a list, a number of items has been added to the list, items themselves are strings (I want to make them as statements).
returns
My simple problem is that end user cannot see the whole statements(strings). I tried the below method but the scrolling won't move.
All of form.setScrollableY(true), form.setScrollabelX(true), and form.setScrollable(true).
This is the code
import javax.microedition.midlet.*;
import com.sun.lwuit.layouts.*;
import com.sun.lwuit.*;
public class HelloLWUITMidlet3 extends MIDlet
{
public void startApp()
{
com.sun.lwuit.Display.init(this);
final com.sun.lwuit.Form form = new com.sun.lwuit.Form("");
final com.sun.lwuit.List l = new com.sun.lwuit.List();
l.addItem("MY favourite Science is computer Sciences");
l.addItem("MY favourite computer Science subject is programming");
l.addItem("MY favourite programming language is java ");
form.setScrollableY(true);
form.setScrollableX(true);
form.addComponent(l);
form.show( );
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
}
First of all, scrolling horizontally back and forth to read content is
really bad UX. This answer will solve only the vertical scrolling issue.
The problem with your code is that you are adding a scrollable (List)
inside another scrollable
(Form). This leads to unexpected results, since it is
not clear which component should handle scrolling. This can be fixed by
using the BorderLayout in the form and placing the list at the center.
...
form.setScrollable(false);
form.setLayout(new BorderLayout());
form.addComponent(BorderLayout.CENTER, l);
...
This will enable vertical scrolling, but the horizontal scrolling will not
work.
Clarification about scrolling:
LWUIT's approach
to scrolling is based on Focus, which means that a Container scrolls
because the focused element is out of the screen. This has the consequence
that LWUIT does not support scrolling elements bigger than the screen and, thus,
that your List will not be scrollable horizontally. (Source:LWUIT mini FAQ )
Suggestion:
The maximum element height is taken as the component height in a List. This
makes the List component adequate to show data that is "pre-formatted" in
a specific way, like contact lists of a folder's details list. If you
want to stack pieces of text of variable length, you should
use a Form with BoxLayoutY and put your text in various TextAreas.
void startApp() {
Display.init()
final Form form = new Form("Title");
addItem(form, "String..");
// as many times as you like
addItem(form, "String..");
form.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
form.setScrollableY(true);
form.show()
}
void addItem(Form f, String s) {
TextArea t = new TextArea(s);
t.setGrowByContent(true);
f.addComponent(t);
}
Related
I'm trying to display image files for the android layout of each screen.
I tried displaying the base menu picture file and image 2 and add them both into the screen. However, I seem to capture the base menu but not the 2nd image.
My function for getting the images, under class name "MyResource'
public function getImage(name:String):Image{
var img:Image = new Image(assetManager.getTexture(name));
return img;
}
My 'main menu' class. It has a bunch of buttons that will redirect it to selected the selected class containing the screens.
switch (btn.name)
{
case "genji":
trace("Genji voice menu was selected.");
app.getScreenManager().getScreen(ScreenManager.SCREEN_GENJI);
break;
}
The screen class that's supposed to display the 2nd image.
public class GenjiScreenClass extends Screens
{
public function GenjiScreenClass(app:StarlingBaseClass)
{
super(app);
}
override public function initialize():void{
trace("I am in GenjiScreenClass initialize() function");
var img:Image = myResource.getImage("basemenu320x480");
var genjiImage:Image = myResource.getImage("GenjiMenuPicture")
this.addChild(genjiImage);
this.addChild(img);
}
}
The image files are all under asset/x1. The base menu image came out but how come the 2nd one didn't?
You add img last:
this.addChild(genjiImage);
this.addChild(img);
This means img is on top of genjiImage covering it up. Depending on the content and size of the images the above one might entirely hide the below one, which can lead to the impression that only the top one is being displayed.
Swap the order of these two statements to solve the problem.
I have a Button (Canvas>Panel>Button) with a complex image (is not square), the issue here is that I want it to execute the on click event when i click on the IMAGE (excluding parts of the image with no opacity) but since the new UI doesn't work with colliders I can't achieve the same click behaviour that could be achieved with a polygon collider, and its feels completely wrong to click outside the button (image) where the alpha is cero (0) and still execute the click events..
I hope my problem is clear enough and someone can help me, thanks in advance.
I found a solution, Unity should have an option to achieve this but at least this works perfectly: http://forum.unity3d.com/threads/none-rectangle-shaped-button.263684/#post-1744521
I found another (probably better) solution for this problem. I used a Collider2D (PolygonCollider2D) to define the clickable shape and then used this RaycastFilter:
using UnityEngine;
using UnityEngine.UI;
[RequireComponent (typeof (RectTransform), typeof (Collider2D))]
public class Collider2DRaycastFilter : MonoBehaviour, ICanvasRaycastFilter
{
Collider2D myCollider;
RectTransform rectTransform;
void Awake ()
{
myCollider = GetComponent<Collider2D>();
rectTransform = GetComponent<RectTransform>();
}
#region ICanvasRaycastFilter implementation
public bool IsRaycastLocationValid (Vector2 screenPos, Camera eventCamera)
{
var worldPoint = Vector3.zero;
var isInside = RectTransformUtility.ScreenPointToWorldPointInRectangle(
rectTransform,
screenPos,
eventCamera,
out worldPoint
);
if (isInside)
isInside = myCollider.OverlapPoint(worldPoint);
return isInside;
}
#endregion
}
Using a collider for this is a bit hacky but the result is much simpler, probably faster and makes it much easier to adjust the clickable shape.
This could be improved by creating a custom alternative to replace the Collider2D but that's a bit too much work for what I need.
i would like to design a component that look like a switch that has 3 position. One neutral position, and upper switch position, when the user click on the upper half of the component and a lower switch position, when the user click the lower half of the component. When the mouse is released the switch go back to neutral position. I have got 3 switch images for these position. I was thinking using a Button then check if the mouse click coordinate is in the upper half or the lower half then set images accordingly. I am looking for any better suggestion, if possible with the use of css for the images (i don't know if it is possible though), or any other suggestion with the use of another component if it is more suitable. Thank you.
Here is what i did, it works...
final Button rstButton = new Button();
final Image rstNeutral = new Image(MyClass.class.getResourceAsStream("images/switch_neutral.png"));
final Image rstUp = new Image(MyClass.class.getResourceAsStream("images/switch_on.png"));
final Image rstDown = new Image(MyClass.class.getResourceAsStream("images/switch_off.png"));
final ImageView rstImage = new ImageView();
rstImage.setImage(rstNeutral);
rstButton.setGraphic(rstImage);
rstButton.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent me) {
double mouseY = me.getY();
double buttonY = rstButton.getLayoutY();
double buttonHeight = rstButton.getHeight();
if(buttonY + mouseY > buttonY + (buttonHeight / 2)) {
rstImage.setImage(rstDown);
} else {
rstImage.setImage(rstUp);
}
}
});
rstButton.setOnMouseReleased(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent arg0) {
rstImage.setImage(rstNeutral);
}
});
I think you should use three component instead of one.
For exemple, you could use three instance of ToogleButton. This component is like a button in appearance, but have a toogle state (clicked/unclicked). I never use it in javaFX but I think you will find enough help on the oracle site (for example : http://docs.oracle.com/javafx/2/ui_controls/toggle-button.htm)
EDIT :
After comment, I think an image of a mechanical switch (http://docs.oracle.com/javafx/2/api/javafx/scene/image/Image.html) could be the solution. If you're showing the switch from the side you can change the rotation of the image according to the state of the switch.
For knowing where the user clicked, locating the position of the button could work.
Another solution could be to had three transparent region on top of the image and intercept the click event on these region, instead of the image. Having never used such a solution, I can really help you more.
Last solution I see could be the use of two another image component on the side of the switch image, showing two arrow, for pulling up or down the switch.
The title is pretty self-explanatory, i'm currently adding PaintListeners to all the children, grand-children and so on, of the control i'd like to paint on. I have graphical errors with Tables and Combos at the moment, the PaintListener apparently doesn't apply to the header or the button in the combo.
How can i do this?
This is the code i use to add the listeners:
List<Control> controls = Lists.newArrayList();
controls.add(composite);
while (! controls.isEmpty()) {
Control c = controls.remove(0);
if (c instanceof Composite) {
controls.addAll(Arrays.asList(((Composite) c).getChildren()));
}
c.addPaintListener(new ControlPaintListener());
}
I'm using .net 2.0 with Visual Studio 2005 and I am trying to add two different toolstrips to the top of the form such that they show up side-by-side. I want it to be like Word 2003, where you can add multiple toolstrips to the same row and have them show up in line with each other, rather than dedicating a row to each toolstrip.
So I added a ToolStripPanel and docked it to the top of the form (I didn't use a ToolStripContainer because I don't need all the extra panels; I just need the one at the top). I added both toolstrips and set their Stretch properties to False. I can get them to show up in the designer window side-by-side, but at runtime the ToolStripPanel separates the toolstrips and gives each toolstrip its own dedicated row. As if to add insult to injury, when i stop debugging and return back to the designer, I am finding that the designer is moving the toolstrips to their own row as well! Am I doing something wrong here?
I have been Googling all day and found some information about a ToolStripPanelRow object, but I don't see an easy way to add toolstrips to it (i.e. it doesn't have a ToolStripPanelRow.Controls.Add method or anything like that), all it has is a Controls() property that returns an Array of control objects, and I haven't had much luck trying to add items to that array. I also found some documentation on the ToolStripPanel.Join method, which sounds like it should do the job, so I tried all 3 overloads but they don't work as advertised. No matter what I do or which options I try, it always adds the new toolstrip to the top of the panel on its own row and pushes everything else down.
In the interests of full disclosure I should warn you that I have the ToolStripPanel and one of the toolstrips added to a baseclass form, and I am trying to add the other toolstrip to a subclass form that inherits from the baseclass form. The ToolStripPanel and ToolStrip in the baseclass form are both declared "Protected Friend", so this should be working. As I mentioned, the subclass form's designer window will allow me to do it (at least, for a time).
If anyone can help me get this working or at least shed some light on why it isn't, I would be extremely grateful.
I created a custom ToolStripPanel so that I could overload the LayoutEngine;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Layout;
namespace CustomGUI
{
class CustomToolStripPanel : ToolStripPanel
{
private LayoutEngine _layoutEngine;
public override LayoutEngine LayoutEngine
{
get
{
if (_layoutEngine == null) _layoutEngine = new CustomLayoutEngine();
return _layoutEngine;
}
}
public override Size GetPreferredSize(Size proposedSize)
{
Size size = base.GetPreferredSize(proposedSize);
foreach(Control control in Controls)
{
int newHeight = control.Height + control.Margin.Vertical + Padding.Vertical;
if (newHeight > size.Height) size.Height = newHeight;
}
return size;
}
}
}
Then the custom LayoutEngine lays out the ToolStrips;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Layout;
namespace CustomGUI
{
class CustomLayoutEngine : LayoutEngine
{
public override bool Layout(object container, LayoutEventArgs layoutEventArgs)
{
Control parent = container as Control;
Rectangle parentDisplayRectangle = parent.DisplayRectangle;
Control [] source = new Control[parent.Controls.Count];
parent.Controls.CopyTo(source, 0);
Point nextControlLocation = parentDisplayRectangle.Location;
foreach (Control c in source)
{
if (!c.Visible) continue;
nextControlLocation.Offset(c.Margin.Left, c.Margin.Top);
c.Location = nextControlLocation;
if (c.AutoSize)
{
c.Size = c.GetPreferredSize(parentDisplayRectangle.Size);
}
nextControlLocation.Y = parentDisplayRectangle.Y;
nextControlLocation.X += c.Width + c.Margin.Right + parent.Padding.Horizontal;
}
return false;
}
}
}
One thing that took a while is that changing the location / size of one ToolStrip item will cause the layout to re-fire, with the controls reordered. So I take a copy of the controls before the layout loop.
And you cant use AddRange(...) to add items to the Custom Panel for some reason - need to Add(...) them one at a time.
hope that helps (it's based on MSDN LayoutEngine Example, fixed for ToolStripPanels)
Wyzfen
System.Windows.Forms.FlowLayoutPanel can do the job.
Just put the ToolStrip controls in it with correct order.
I think in your case you can get away with just setting the LayoutStyle on your ToolStrip to ToolStripLayoutStyle.HorizontalStackWithOverflow rather than need your own custom LayoutEngine.
I asked a different question on a similar topic on how to handle layout with dynamic items to have better control of the overflow.