Resize tabs only when double click on tab name - javafx-2

I have this code which resizes tab when it's clicked twice no matter where I click on the tab.
VBox stackedTitledPanes = createStackedTitledPanes();
ScrollPane scroll = makeScrollable(stackedTitledPanes);
final TabPane tabPane = new TabPane();
final BorderPane mainPane = new BorderPane();
final Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
tabPane.setStyle("-fx-font-size: 12pt;"); // Set global size for the font
// Create Tabs
Tab tabA = new Tab();
tabPane.setOnMouseClicked(new EventHandler<MouseEvent>()
{
private double sizeX, sizeY;
private boolean first = true;
#Override
public void handle(MouseEvent me)
{
if (first)
{
sizeX = mainPane.getWidth();
sizeY = mainPane.getHeight();
first = false;
}
if (me.getButton().equals(MouseButton.PRIMARY) && me.getClickCount() % 2 == 0)
{
if (sizeX != mainPane.getWidth() || sizeY != mainPane.getHeight())
{
mainPane.setPrefSize(sizeX, sizeY);
}
else
{
mainPane.setPrefSize(primaryScreenBounds.getWidth(), primaryScreenBounds.getHeight());
}
}
}
});
tabA.setText("Main Component");
tabA.setContextMenu(makeTabContextMenu(tabA, tabPane)); // Set right mouse click menu
// Add something in Tab
StackPane tabA_stack = new StackPane();
tabA_stack.setAlignment(Pos.CENTER);
tabA_stack.getChildren().add(scroll);
tabA.setContent(tabA_stack);
tabPane.getTabs().add(tabA);
Tab tabB = new Tab();
tabB.setText("Second Component");
tabB.setContextMenu(makeTabContextMenu(tabB, tabPane)); // Set right mouse click menu
// Add something in Tab
StackPane tabB_stack = new StackPane();
tabB_stack.setAlignment(Pos.CENTER);
tabB_stack.getChildren().add(new Label("Label#Tab B"));
tabB.setContent(tabB_stack);
tabPane.getTabs().add(tabB);
Tab tabC = new Tab();
tabC.setText("Last Component");
tabC.setContextMenu(makeTabContextMenu(tabC, tabPane)); // Set right mouse click menu
// Add something in Tab
StackPane tabC_vBox = new StackPane();
tabC_vBox.setAlignment(Pos.CENTER);
tabC_vBox.getChildren().add(new Label("Label#Tab C"));
tabC.setContent(tabC_vBox);
tabPane.getTabs().add(tabC);
mainPane.setCenter(tabPane);
mainPane.setPrefSize(300, 500);
//mainPane.setLayoutX(5); // Horizontal Position
mainPane.setLayoutY(32); // Vertical Position
scroll.setPrefSize(395, 580);
scroll.setLayoutX(5);
scroll.setLayoutY(32);
Can you tell me how I can modify the code in a way that I can size the tab only when I double click on a tab name?

to make it simple,
Create a EventHandler
EventHandler eventHandler = new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent me)
{
if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) {
if (mouseEvent.getClickCount() == 2) {
...
...
...
} }
}
}
And add this eventhandler to every tab's node.
node.setOnMouseClicked(eventHandler);
This is the only choice you have.

Related

Xamarin.Android how i can get position and margin to elements which are generated from the code?

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));

Custom Toolbar in UINavigation Controller

I am having trouble understanding what approach to take to customize my own Toolbar in Xamarin.ios. The Navigation controller comes with its own default toolbar but how can i change the height and have my own buttons, background image.
What is the best approach for the above ?
You can create a custom navigationBar as you want .
public class xxxViewController: UIViewController
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
NavigationController.NavigationBar.Hidden = true;
double height = IsiphoneX();
UIView backView = new UIView()
{
BackgroundColor = UIColor.White,
Frame = new CGRect(0,20,UIScreen.MainScreen.Bounds.Width, height),
};
UIButton backBtn = new UIButton() {
Frame = new CGRect(20, height-44, 40, 44),
Font = UIFont.SystemFontOfSize(18),
} ;
backBtn.SetTitle("Back", UIControlState.Normal);
backBtn.SetTitleColor(UIColor.Blue, UIControlState.Normal);
backBtn.AddTarget(this,new Selector("GoBack"),UIControlEvent.TouchUpInside);
UILabel titleLabel = new UILabel() {
Frame=new CGRect(UIScreen.MainScreen.Bounds.Width/2-75, 0,150, height),
Font = UIFont.SystemFontOfSize(20),
Text = "xxx",
TextColor = UIColor.Black,
Lines = 0,
};
UILabel line = new UILabel() {
Frame = new CGRect(0, height, UIScreen.MainScreen.Bounds.Width, 0.5),
BackgroundColor = UIColor.Black,
};
backView.AddSubview(backBtn);
backView.AddSubview(titleLabel);
backView.AddSubview(line);
View.AddSubview(backView);
}
double IsiphoneX()
{
double height = 44;
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
if (UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom > 0.0)
{
height = 64;
}
}
return height;
}
[Export("GoBack")]
void GoBack()
{
NavigationController.PopViewController(true);
}
public override void ViewWillDisappear(bool animated)
{
base.ViewWillDisappear(animated);
NavigationController.NavigationBar.Hidden = false;
}
}
You can set the property of title , backButton and navigationBar as you need (such as text , color ,BackgroundColor ,font e.g.)

JavaFX: setting background color for Text controls

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.

Can't get new iOS 7 camera to scale inside UIPopoverController

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.

Dragging object to wrong position and Scrolling of panel in C#

I am working for one application in C#, in which I have to show some control in a panel. Controls can be dragable. All is working fine except one thing, mentioned as follows
Suppose i have a panel(controls container) in Main-Panel. Main panel has AutoScroll property true.So Main-Panel shows scroll bars when inner panel(controls container) has the height more than the height of Main-Panel.
suppose inner panel is showing in two areas due to large height than main-panel.When i add a picturebox in inner panel, then picturebox is showing in upper area, because i set the location 10,10 in start.
when i try to drag this picturebox to down,it move with the mouse movement.If picturebox enters in lower area of inner panel, scrollbars of Main-panel automatically go down and mouse position is automatically go down according to current position and picturebox also goes down to that position.but it was not desirable position.
my code is simple for moving objects.
public static void Init(Control control, Control container, Direction direction)
{
bool Dragging = false;
Point DragStart = Point.Empty;
control.MouseDown += delegate(object sender, MouseEventArgs e)
{
Dragging = true;
DragStart = e.Location;
control.Capture = true;
HoldOn.Invoke(sender, e);
};
control.MouseUp += delegate(object sender, MouseEventArgs e)
{
Dragging = false;
control.Capture = false;
};
control.MouseMove += delegate(object sender, MouseEventArgs e)
{
if (Dragging)
{
control.Location = new Point(e.X - DragStart.X + control.Location.X,
e.Y - DragStart.Y + control.Location.Y);
}
};
}
I have added a picture to show my problem.
I hope it will help for you to understand.

Resources