I'm using LWUIT to create J2ME application. I used GridLayout to add the controls but they are not aligned.
Code:
flowLayout = new FlowLayout();
roundsPage.setLayout(flowLayout);
try {
image = image.createImage("/11.png"); // All image 40 x 40
starImage = Image.createImage("/j1.png");
smileImage = Image.createImage("/j2.png");
imgClock = Image.createImage("/clock.jpg");
imageTeam = Image.createImage("/name.png");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dateLabel=new Label("14-02-2012, Round1 ");
dateLabel.getStyle().setBgColor(0x8b8989);
dateLabel.getStyle().setFgColor(0xffffff);
roundsPage.addComponent(dateLabel);
//int screenWidth = Display.getInstance().getDisplayWidth();
Container tabContainer1 = new Container(new BoxLayout(BoxLayout.Y_AXIS));
tabContainer1.addComponent(new Button("Click"));
tabContainer1.addComponent(new Button("Click"));
tabContainer1.addComponent(new Button("Click"));
tabContainer1.addComponent(new Button("Click"));
Container tabContainer2 = new Container(new BoxLayout(BoxLayout.X_AXIS));
team1=new Label(starImage);
team1.setText("Villarreal");
team1.setTextPosition(Component.BOTTOM);
//team1.setWidth(10);
//team1.getStyle().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN ,Font.SIZE_SMALL));
tabContainer2.addComponent(team1);
tabContainer2.setWidth(100);
clockLabel=new Label(imgClock);
clockLabel.setText("18:00");
clockLabel.setTextPosition(Component.RIGHT);
tabContainer2.addComponent(clockLabel);
teamLabel=new Label(imageTeam);
teamLabel.setText("El Madrigal");
teamLabel.setTextPosition(Component.RIGHT);
tabContainer2.addComponent(teamLabel);
team2=new Label(smileImage);
team2.setText("Betis");
team2.setTextPosition(Component.BOTTOM);
team2.setFocusable(true);
tabContainer2.addComponent(team2);
Container tabContainer3 = new Container(new BoxLayout(BoxLayout.Y_AXIS));
tabContainer3.addComponent(new Button("Click"));
tabContainer3.addComponent(new Button("Click"));
tabContainer3.addComponent(new Button("Click"));
tabContainer3.addComponent(new Button("Click"));
TabbedPane tabbbed = new TabbedPane();
tabbbed.addTab(null, image, tabContainer1 );
tabbbed.addTab(null, image, tabContainer2);
tabbbed.addTab(null, image, tabContainer3);
roundsPage.addComponent(tabbbed);
Thanks in advance.
Don't use like this "14-02-2012, Round1 ". Get the width of the display and set the preferredW on dateLabel. For getting screen width use this,
int width = Display.getInstance().getDisplayWidth();.
Also Don't use TabbedPane. Use Tabs. Add the button in to addTab and set the width of the button. Because each tab having same width and height when you use TabbedPane. Thats an issue.
Related
Problems with position elements which generating from code
i will try to place it in center and give them margin (left right) from previous elements.
tried use LinearLayout, RowLayout, but all result are the same (staying center in each other).
Like a Sample
public void testImageAdd(object sender, EventArgs eventArgs)
{
RelativeLayout relativeLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams relativeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
RelativeLayout.LayoutParams relativeLayoutParams2 = new RelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent);
relativeLayoutParams.SetMargins(30,20,30,0);
relativeLayoutParams.AddRule(LayoutRules.CenterHorizontal);
#region team1 Elements
ImageView firstTeamLogo = new ImageView(this);
firstTeamLogo.LayoutParameters = relativeLayoutParams;
TextView firstTeamText = new TextView(this);
firstTeamText.Text = "testTeam1";
firstTeamText.LayoutParameters = relativeLayoutParams;
var firstTeamLogoBitmap = ImageDownloader.GetImageBitmapFromUrl("");
firstTeamLogo.SetImageBitmap(firstTeamLogoBitmap);
#endregion
#region team2 Elements
ImageView secondTeamLogo = new ImageView(this);
secondTeamLogo.LayoutParameters = relativeLayoutParams;
TextView secondTeamText = new TextView(this);
secondTeamText.Text = "testTeam2";
secondTeamText.LayoutParameters = relativeLayoutParams;
var secondTeamLogoTeamLogoBitmap = ImageDownloader.GetImageBitmapFromUrl("");
secondTeamLogo.SetImageBitmap(secondTeamLogoTeamLogoBitmap);
#endregion
TextView versusText = new TextView(this);
versusText.Text = "vs";
versusText.LayoutParameters = relativeLayoutParams;
relativeLayout.AddView(firstTeamLogo);
relativeLayout.AddView(firstTeamText);
relativeLayout.AddView(versusText);
relativeLayout.AddView(secondTeamText);
relativeLayout.AddView(secondTeamLogo);
SetContentView(relativeLayout, relativeLayoutParams2);
What did i do wrong? And i think i'm calling the drawing of elements incorrectly (is there a bit of code duplication?).
Replace RelativeLayout with LinearLayout , your code works fine on my side .
Update
You can add relativeLayout.SetGravity(GravityFlags.CenterVertical); to make the elements center in vertical , but another problem would happen ,all the elements would be placed to the center of the screen(vertically).
To solve the problem we should add another LinearLayout as root layout.
Refer to the following code
LinearLayout relativeLayout = new LinearLayout(this);
relativeLayout.SetGravity(GravityFlags.CenterVertical);
relativeLayout.LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
LinearLayout.LayoutParams relativeLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
relativeLayoutParams.SetMargins(10, 20, 30, 10);
#region team1 Elements
ImageView firstTeamLogo = new ImageView(this);
firstTeamLogo.LayoutParameters = relativeLayoutParams;
TextView firstTeamText = new TextView(this);
firstTeamText.Text = "testTeam1";
firstTeamText.LayoutParameters = relativeLayoutParams;
//var firstTeamLogoBitmap = ImageDownloader.GetImageBitmapFromUrl("");
//firstTeamLogo.SetImageBitmap(firstTeamLogoBitmap);
firstTeamLogo.SetBackgroundResource(Resource.Drawable.myIcon);
#endregion
#region team2 Elements
ImageView secondTeamLogo = new ImageView(this);
secondTeamLogo.LayoutParameters = relativeLayoutParams;
TextView secondTeamText = new TextView(this);
secondTeamText.Text = "testTeam2";
secondTeamText.LayoutParameters = relativeLayoutParams;
//var secondTeamLogoTeamLogoBitmap = ImageDownloader.GetImageBitmapFromUrl("");
//secondTeamLogo.SetImageBitmap(secondTeamLogoTeamLogoBitmap);
secondTeamLogo.SetBackgroundResource(Resource.Drawable.a);
#endregion
TextView versusText = new TextView(this);
versusText.Text = "vs";
versusText.LayoutParameters = relativeLayoutParams;
relativeLayout.AddView(firstTeamLogo);
relativeLayout.AddView(firstTeamText);
relativeLayout.AddView(versusText);
relativeLayout.AddView(secondTeamText);
relativeLayout.AddView(secondTeamLogo);
LinearLayout parent = new LinearLayout(this);
parent.SetGravity(GravityFlags.Top);
parent.AddView(relativeLayout);
SetContentView(parent, new LinearLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent));
I am able to add ImageIcons to a JTextPane, but when I add them they show up in the center of the JTextPane. I can't find a way to control where they are placed on the JTextPane. Can someone please help me with this?
This method is making the JTextPane:
private void loadTextPanel(JPanel contentPane) {
chatLogPanel = new JPanel();
chatLogPanel.setLayout(null);
EmptyBorder eb = new EmptyBorder(new Insets(10, 10, 10, 10));
DefaultStyledDocument document = new DefaultStyledDocument();
chatLog = new JTextPane(document);
chatLog.setEditorKit(new WrapEditorKit());
chatLog.setBorder(eb);
chatLog.setMargin(new Insets(5, 5, 5, 5));
chatLogScrollPane = new JScrollPane(chatLog);
addComponent(chatLogPanel, chatLogScrollPane, 0, 0, 500, 240);
addComponent(contentPane, chatLogPanel, 0, 40, 500, 240);
}
This is the code I'm using to add a string to the Panel:
private static void appendToChatLog(JTextPane tp, String msg, Color c) {
chatLog.setEditable(true);
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);
aset = sc.addAttribute(aset, StyleConstants.FontFamily, "Lucida Console");
aset = sc.addAttribute(aset, StyleConstants.Alignment, Integer.valueOf(3));
int len = tp.getDocument().getLength();
tp.setCaretPosition(len);
tp.setCharacterAttributes(aset, false);
tp.replaceSelection(msg);
chatLog.setEditable(false);
}
And this is what I'm currently using to add the image to the JTextPane:
BufferedImage image = generateBufferedImage(message.getImage());
Icon icon = new ImageIcon(image);
StyleContext context = new StyleContext();
StyledDocument document = (StyledDocument) chatLog.getDocument();
Style labelStyle = context.getStyle(StyleContext.DEFAULT_STYLE);
JLabel label = new JLabel(icon);
StyleConstants.setComponent(labelStyle, label);
try {
document.insertString(document.getLength(), "Ignored", labelStyle);
} catch (BadLocationException badLocationException) {
badLocationException.printStackTrace();
}
To insert a component to a JTextPane, and display it like a character, use the insertComponent method.
To insert an Icon instead, use the insertIcon method.
Quite intuitive isn't it ;)
I'm using a TextFlow and some Text items to show a styled text, but i cant find a way to set a simple background color for the Text items.
I can set the fill color and font but it does not have a java method or css property that sets its background color.
Based on this solution, this is a quick implementation of a method to provide background coloring for all the Text nodes within a FlowPane, using CSS and the ability to set a series of paint values separated by commas (as much as Text items) and insets for each one of them:
private FlowPane flow;
private Scene scene;
#Override
public void start(Stage primaryStage) {
Text text0 = new Text("These are several ");
Text text1 = new Text("Text Nodes ");
Text text2 = new Text("wrapped in ");
Text text3 = new Text("a FlowPane");
text0.setFill(Color.WHEAT);
text0.setFont(new Font("Times New Roman", 20));
text1.setFill(Color.WHITE);
text1.setFont(new Font("Verdana", 32));
text2.setFill(Color.WHITESMOKE);
text2.setFont(new Font("Arial", 24));
text3.setFill(Color.WHITESMOKE);
text3.setFont(new Font("Arial", 18));
flow = new FlowPane(text0, text1, text2, text3);
scene = new Scene(flow, 300, 200);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
setBackgroundColors();
flow.needsLayoutProperty().addListener((obs,d,d1)->setBackgroundColors());
}
private void setBackgroundColors(){
final Bounds out = flow.getBoundsInLocal();
final StringBuilder sbColors = new StringBuilder();
final StringBuilder sbInsets = new StringBuilder();
AtomicInteger cont = new AtomicInteger();
flow.getChildrenUnmodifiable().forEach(n->{
sbColors.append("hsb(")
.append((((double)cont.get())/((double)flow.getChildren().size()))*360d)
.append(", 60%, 90%)");
Bounds b = ((Text)n).getBoundsInParent();
sbInsets.append(b.getMinY()).append(" ");
sbInsets.append(Math.min(scene.getWidth(),out.getMaxX())-b.getMaxX()).append(" ");
sbInsets.append(Math.min(scene.getHeight(),out.getMaxY())-b.getMaxY()).append(" ");
sbInsets.append(b.getMinX());
if(cont.getAndIncrement()<flow.getChildren().size()-1){
sbColors.append(", ");
sbInsets.append(", ");
}
});
flow.setStyle("-fx-background-color: "+sbColors.toString()+"; -fx-background-insets: "+sbInsets.toString()+";");
}
This will lead to this:
and after resizing the scene:
EDIT
Based on the OP request of using a TextFlow layout instead of a FlowPane, since Text nodes can be spanned over several lines within a TextFlow, the given solution will no longer be valid, as the bounding box of each text node will overlap others.
As a workaround, we can split the Text nodes in single word Text nodes, while keeping the same background color for those in the same original phrase.
I won't go into the splitting logic, but I will add a list of indices, where each index maps the text node with its index of background color.
private FlowPane flow;
private Scene scene;
private final List<Integer> indices=Arrays.asList(0,0,0,1,1,2,2,3,3);
#Override
public void start(Stage primaryStage) {
List<Text> text0 = Arrays.asList(new Text("These "), new Text("are "), new Text("several "));
List<Text> text1 = Arrays.asList(new Text("Text "), new Text("Nodes "));
List<Text> text2 = Arrays.asList(new Text("wrapped "), new Text("in "));
List<Text> text3 = Arrays.asList(new Text("a "), new Text("FlowPane"));
text0.forEach(t->t.setFill(Color.WHEAT));
text0.forEach(t->t.setFont(new Font("Times New Roman", 20)));
text1.forEach(t->t.setFill(Color.WHITE));
text1.forEach(t->t.setFont(new Font("Verdana", 32)));
text2.forEach(t->t.setFill(Color.WHITESMOKE));
text2.forEach(t->t.setFont(new Font("Arial", 24)));
text3.forEach(t->t.setFill(Color.WHITESMOKE));
text3.forEach(t->t.setFont(new Font("Arial", 18)));
flow = new FlowPane();
flow.getChildren().addAll(text0);
flow.getChildren().addAll(text1);
flow.getChildren().addAll(text2);
flow.getChildren().addAll(text3);
scene = new Scene(flow, 300, 200);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
setBackgroundColors();
flow.needsLayoutProperty().addListener((obs,d,d1)->setBackgroundColors());
}
private void setBackgroundColors(){
final Bounds out = flow.getBoundsInLocal();
final StringBuilder sbColors = new StringBuilder();
final StringBuilder sbInsets = new StringBuilder();
AtomicInteger cont = new AtomicInteger();
flow.getChildrenUnmodifiable().forEach(n->{
sbColors.append("hsb(")
.append((double)indices.get(cont.get())/(double)(indices.get(flow.getChildren().size()-1)+1)*360d)
.append(", 60%, 90%)");
Bounds b = ((Text)n).getBoundsInParent();
sbInsets.append(b.getMinY()).append(" ");
sbInsets.append(Math.min(scene.getWidth(),out.getMaxX())-b.getMaxX()-1).append(" ");
sbInsets.append(Math.min(scene.getHeight(),out.getMaxY())-b.getMaxY()).append(" ");
sbInsets.append(b.getMinX());
if(cont.getAndIncrement()<flow.getChildren().size()-1){
sbColors.append(", ");
sbInsets.append(", ");
}
});
flow.setStyle("-fx-background-color: "+sbColors.toString()+"; -fx-background-insets: "+sbInsets.toString()+";");
}
This FlowPane now behaves as a TextFlow:
There is no background for Text objects. You'd either have to group it with a shape (rectangle, ellipse, etc) and set the color of that shape, or you could put the objects inside a StackPane and set the background color of the StackPane.
I have a TextField in my JavaFX application. I want to programmatically display a message on the right side of the text (like the validation message). I thought of using Popup and setting the Label with message in that Popup. But I'm not sure how I can position this to the right side of the text field. Below is the sample code for this. Can you please help me with this?
public void start(Stage primaryStage) {
primaryStage.setTitle("JavaFX Welcome");
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25, 25, 25, 25));
Text scenetitle = new Text("Welcome");
scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20));
grid.add(scenetitle, 0, 0, 2, 1);
Label userName = new Label("User Name:");
grid.add(userName, 0, 1);
TextField userTextField = new TextField();
grid.add(userTextField, 1, 1);
Label pw = new Label("Password:");
grid.add(pw, 0, 2);
PasswordField pwBox = new PasswordField();
grid.add(pwBox, 1, 2);
Label label=new Label();
label.setText("This is an error message");
final Text actiontarget = new Text();
grid.add(actiontarget, 1, 6);
final Popup popup = new Popup();
popup.getContent().add(label);
//Want to display this popup to the right of the userTextField.
Scene scene = new Scene(grid, 300, 275);
primaryStage.setScene(scene);
primaryStage.show();
}
After showing the stage, do
Bounds userTextFieldBounds = userTextField.getBoundsInLocal();
Point2D popupLocation = userTextField.localToScreen(userTextFieldBounds.getMaxX(), userTextFieldBounds.getMinY());
popup.show(userTextField, popupLocation.getX(), popupLocation.getY());
The localToScreen(...) method was introduced in Java 8; if you are in an earlier version you will need
Bounds userTextFieldBounds = userTextField.getBoundsInLocal();
Point2D popupLocation = userTextField.localToScene(userTextFieldBounds.getMaxX(), userTextFieldBounds.getMinY());
popup.show(userTextField,
popupLocation.getX()+scene.getX()+primaryStage.getX(),
popupLocation.getY()+scene.getY()+primaryStage.getY());
My iOS 6 code to show the camera in a UIPopoverController works fine but iOS won't scale the camera view. Please see images below. Any suggestions would be appreciated.
Edit
public class NoRotationUIImagePickerController : UIImagePickerController
{
public override bool ShouldAutorotate ()
{
return false;
}
}
//place imagePicker into a container so that we can control the size of the popover
container = new UIViewController();
container.ContentSizeForViewInPopover = new SizeF(parentViewController.View.Frame.Width, parentViewController.View.Frame.Height);
container.View.AddSubview(_imagePicker.View);
_popOver = new UIPopoverController (container);
//If no camera is available, return false and do nothing.
if (IsCameraHardwareAvailable())
{
_imagePicker.Delegate = new PopUpGalleryPickerDelegate (_popOver, _imageSelected);
_imagePicker.SourceType = UIImagePickerControllerSourceType.Camera;
_imagePicker.AllowsEditing = false;
_imagePicker.MediaTypes = new string[] {"public.image"};
RectangleF popRectangle = new RectangleF (new PointF(parentViewController.View.Frame.Width/2, parentViewController.View.Frame.Height/2), new SizeF (1, 1));
_popOver.PresentFromRect(popRectangle, parentViewController.View, 0, true);
_imagePicker.View.Frame = container.View.Frame; //change to frame must come after popover is presented.
}
else
{
cameraAvailable = false;
}
The solution I ended up with was to make the camera full screen instead of using a popover controller.