i have some problem with this method. it works fine, but with one little problem. there is too little time among i call this method. so only the last String is printed on a label. but i want that the next String starting printed, only after previous String is finished.
Sorry for my English((
public void some(final String s) {
final Animation animation = new Transition() {
{
setCycleDuration(Duration.millis(2000));
}
protected void interpolate(double frac) {
final int length = s.length();
final int n = Math.round(length * (float) frac);
javafx.application.Platform.runLater(new Runnable() {
#Override
public void run() {
status.setValue(s.substring(0, n));
}
}
);
}
};
animation.play();
}
Use the following code to get a typewriting effect.
public void AnimateText(Label lbl, String descImp) {
String content = descImp;
final Animation animation = new Transition() {
{
setCycleDuration(Duration.millis(2000));
}
protected void interpolate(double frac) {
final int length = content.length();
final int n = Math.round(length * (float) frac);
lbl.setText(content.substring(0, n));
}
};
animation.play();
}
I don't know if it is an effect that you are trying to achieve, but I have created (ugly) demo how you can do this with TimeLine
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
IntegerProperty letters= new SimpleIntegerProperty(0);
Label label = new Label();
Button animate = new Button("animate");
letters.addListener((a, b, c) -> {
label.setText("animate".substring(0, c.intValue()));
});
animate.setOnAction((e)->{
Timeline timeline = new Timeline();
KeyValue kv = new KeyValue(letters, "animate".length());
KeyFrame kf = new KeyFrame(Duration.seconds(3), kv);
timeline.getKeyFrames().add(kf);
timeline.play();
});
BorderPane pane = new BorderPane(label, null, null, animate, null);
primaryStage.setScene(new Scene(pane, 300,300));
primaryStage.show();
}
}
Related
I have a problem. Right now I have two imagebuttons. When I click on the first button to increase the image the button next to it is still availble in the screen. I dont know to set the selected screen in the foreground?
Can anybody help?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bewerbung);
final View thumb1View = findViewById(R.id.thumb_button_1);
thumb1View.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
zoomImageFromThumb(thumb1View, R.drawable.anschreiben1);
}
});
final View thumb2View = findViewById(R.id.thumb_button_2);
thumb2View.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
zoomImageFromThumb(thumb2View, R.drawable.anschreiben2);
}
});
mShortAnimationDuration = getResources().getInteger(
android.R.integer.config_shortAnimTime);
}
private void zoomImageFromThumb(final View thumbView, int imageResId) {
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
final ImageView expandedImageView = (ImageView) findViewById(
R.id.expanded_image);
expandedImageView.setImageResource(imageResId);
final Rect startBounds = new Rect();
final Rect finalBounds = new Rect();
final Point globalOffset = new Point();
thumbView.getGlobalVisibleRect(startBounds);
findViewById(R.id.container)
.getGlobalVisibleRect(finalBounds, globalOffset);
startBounds.offset(-globalOffset.x, -globalOffset.y);
finalBounds.offset(-globalOffset.x, -globalOffset.y);
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
> (float) startBounds.width() / startBounds.height()) {
startScale = (float) startBounds.height() / finalBounds.height();
float startWidth = startScale * finalBounds.width();
float deltaWidth = (startWidth - startBounds.width()) / 2;
startBounds.left -= deltaWidth;
startBounds.right += deltaWidth;
} else {
startScale = (float) startBounds.width() / finalBounds.width();
float startHeight = startScale * finalBounds.height();
float deltaHeight = (startHeight - startBounds.height()) / 2;
startBounds.top -= deltaHeight;
startBounds.bottom += deltaHeight;
}
thumbView.setAlpha(0f);
expandedImageView.setVisibility(View.VISIBLE);
expandedImageView.setPivotX(0f);
expandedImageView.setPivotY(0f);
AnimatorSet set = new AnimatorSet();
set
.play(ObjectAnimator.ofFloat(expandedImageView, View.X,
startBounds.left, finalBounds.left))
.with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
startBounds.top, finalBounds.top))
.with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X,
startScale, 1f)).with(ObjectAnimator.ofFloat(expandedImageView,
View.SCALE_Y, startScale, 1f));
set.setDuration(mShortAnimationDuration);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mCurrentAnimator = null;
}
#Override
public void onAnimationCancel(Animator animation) {
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
final float startScaleFinal = startScale;
expandedImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
AnimatorSet set = new AnimatorSet();
set.play(ObjectAnimator
.ofFloat(expandedImageView, View.X, startBounds.left))
.with(ObjectAnimator
.ofFloat(expandedImageView,
View.Y, startBounds.top))
.with(ObjectAnimator
.ofFloat(expandedImageView,
View.SCALE_X, startScaleFinal))
.with(ObjectAnimator
.ofFloat(expandedImageView,
View.SCALE_Y, startScaleFinal));
set.setDuration(mShortAnimationDuration);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
thumbView.setAlpha(1f);
expandedImageView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
#Override
public void onAnimationCancel(Animator animation) {
thumbView.setAlpha(1f);
expandedImageView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
}
});
}
}
I am learning custom views in android.
I made one custom view, with a rectangle and a text. The code of the custom view is:
public class TileGenerator extends View {
// rectangle parameters
private Rect rect = new Rect();
private Paint rectPaint = new Paint();
private Integer rectEndX;
private Integer rectEndY;
private Integer rectStartX;
private Integer rectStartY;
private Integer rectFillColor;
private Float rectTextStartX;
private Float rectTextStartY;
//rectangle text
private String rectText;
private Paint rectTextPaint = new Paint();
public TileGenerator(Context context) {
super(context);
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void setTileTitleText(String rectText) {
this.rectText = rectText;
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
rectEndX = getrectEndX();
rectEndY = getrectEndY();
rectStartX = getRectStartX();
rectStartY = getRectStartY();
rectTextStartX = rectEndX/4f + rectStartX;
rectTextStartY = 3.5f * rectEndY/4f + rectStartY;
rectTextPaint.setTextSize(rectEndY/8);
rectTextPaint.setColor(Color.BLACK);
rect.set(rectStartX,rectStartY,rectEndX,rectEndY);
rectPaint.setColor(getRectFillColor());
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(rect, rectPaint);
canvas.drawText(rectText,rectTextStartX,rectTextStartY,rectTextPaint );
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
}
public Integer getrectEndX() {
return rectEndX;
}
public void setrectEndX(Integer rectEndX) {
this.rectEndX = rectEndX;
}
public Integer getrectEndY() {
return rectEndY;
}
public void setrectEndY(Integer rectEndY) {
this.rectEndY = rectEndY;
}
public Integer getRectStartX() {
return rectStartX;
}
public void setRectStartX(Integer rectStartX) {
this.rectStartX = rectStartX;
}
public Integer getRectStartY() {
return rectStartY;
}
public void setRectStartY(Integer rectStartY) {
this.rectStartY = rectStartY;
}
public Integer getRectFillColor() {
return rectFillColor;
}
public void setRectFillColor(Integer rectFillColor) {
this.rectFillColor = rectFillColor;
}
public String getRectText() {
return rectText;
}
}
After that I created an blank activity. I am doing all with JAVA code. No XML. Then I try to add above custom view to a gridview layout. I want to add two custom views with different text in a horizontal gridview. So far my code is as below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GridLayout gridLayout = new GridLayout(this);
// first custom view
CustomRectWithText customRectWithText = new CustomRectWithText(this);
customRectWithText.setRectEndX(200);
customRectWithText.setRectEndY(200);
customRectWithText.setRectStartX(2);
customRectWithText.setRectStartY(2);
customRectWithText.setImage(image);
customRectWithText.setRectText("Text");
customRectWithText.setRectFillColor(Color.BLUE);
gridLayout.addView(customRectWithText);
// second custom view
CustomRectWithText customRectWithText1 = new CustomRectWithText(this);
customRectWithText1.setRectEndX(400);
customRectWithText1.setRectEndY(200);
customRectWithText1.setRectStartX(200 + 5);
customRectWithText1.setRectStartY(2);
customRectWithText1.setTileTitleText("Text 1");
customRectWithText1.setRectFillColor(Color.GREEN);
gridLayout.addView(customRectWithText1);
setContentView(gridLayout);
}
But still I am not getting both of the rectangles in a grid view. Only one rectangle is displayed at a time. In above case only first custom view is displayed.
Where am I doing wrong.
All I want is to make a repetitive rectangle of varying labels of any size inside a grid view.
Is this the way to do it. I mean is there any other way around.
I dont want to use ListItems.
Sorry but i do not have enough repo to comment.
But why dont you make an adapter?
Gridview behaves same as listView.
Use adapter to fill your grid.
This is the proper way to populate listView and gridView also.
I have some signal processing data which gets fed at roughly at 50Hz. I need to update a rectangle's opacity based on the signal value in real time. I am trying to develop the UI in JavaFX 8.
For time being I am simulating the signal value using random number generator in JavaFX service in my code.
I am using Platform.runLater to update the UI, however this doesn't update values in real time, I read through similar problems encountered by others and the normal suggestion is that not to call Platform.runLater often but to batch the updates.
In my case if I batch my updates, the frequency at which the opacity changes will not be equal to the signal frequency.
Any thoughts on how to achieve this?
public class FlickerController
{
#FXML
private Rectangle leftBox;
#FXML
private Rectangle rightBox;
#FXML
private ColorPicker leftPrimary;
#FXML
private ColorPicker leftSecondary;
#FXML
private ColorPicker rightPrimary;
#FXML
private ColorPicker rightSecondary;
#FXML
private Slider leftFrequency;
#FXML
private Slider rightFrequency;
#FXML
private Button startButton;
#FXML
private Label leftfreqlabel;
#FXML
private Label rightfreqlabel;
#FXML
private Label rightBrightness;
#FXML
private Label leftBrightness;
private boolean running = false;
DoubleProperty leftopacity = new SimpleDoubleProperty(1);
DoubleProperty rightopacity = new SimpleDoubleProperty(1);
private FlickerThread ftLeft;
private FlickerThread ftRight;
public void initialize()
{
leftopacity.addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue)
{
Platform.runLater(new Runnable()
{
#Override
public void run()
{
double brightness = leftopacity.doubleValue();
leftBrightness.setText(""+brightness);
leftBox.opacityProperty().set(brightness);
}
});
}
});
rightopacity.addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue)
{
Platform.runLater(new Runnable()
{
#Override
public void run()
{
double brightness = rightopacity.doubleValue();
rightBrightness.setText(""+brightness);
rightBox.opacityProperty().set(brightness);
}
});
}
});
startButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event)
{
if(running)
{
synchronized(this)
{
running=false;
}
startButton.setText("Start");
}
else
{
running=true;
ftLeft = new FlickerThread((int)leftFrequency.getValue(),leftopacity);
ftRight = new FlickerThread((int)rightFrequency.getValue(), rightopacity);
try
{
ftLeft.start();
ftRight.start();
}
catch(Throwable t)
{
t.printStackTrace();
}
startButton.setText("Stop");
}
}
});
leftFrequency.valueProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue)
{
leftfreqlabel.setText(newValue.intValue()+"");
}
});
rightFrequency.valueProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue)
{
rightfreqlabel.setText(newValue.intValue()+"");
}
});
}
class FlickerThread extends Service<Void>
{
private long sleeptime;
DoubleProperty localval = new SimpleDoubleProperty(1) ;
public FlickerThread(int freq, DoubleProperty valtoBind)
{
this.sleeptime = (1/freq)*1000;
valtoBind.bind(localval);
}
#Override
protected Task <Void>createTask()
{
return new Task<Void>() {
#Override
protected Void call() throws Exception
{
while(running)
{
double val = Math.random();
System.out.println(val);
localval.setValue(val);
Thread.sleep(sleeptime);
}
return null;
}
};
}
}
}
class FlickerThread extends Thread
{
private long sleeptime;
final AtomicReference<Double> counter = new AtomicReference<>(new Double(-1.0));
private Label label;
private Rectangle myrect;
public FlickerThread(int freq, Label label,Rectangle rect)
{
this.sleeptime = (long) ((1.0/freq)*1000.0);
System.out.println("Sleep time is "+sleeptime);
this.label = label;
this.myrect = rect;
}
#Override
public void run() {
double count = 1.0 ;
while (running) {
count = Math.random();
if (counter.getAndSet(count) == -1) {
updateUI(counter, label,myrect);
try
{
Thread.sleep(sleeptime);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
private void updateUI(final AtomicReference<Double> counter,
final Label label, final Rectangle myrect) {
Platform.runLater(new Runnable() {
#Override
public void run() {
double val = counter.getAndSet(-1.0);
final String msg = String.format("Brt: %,f", val);
label.setText(msg);
myrect.opacityProperty().set(val);
}
});
}
You have a calculation error in your code.
Consider:
1/100*1000=0
But:
1.0/100*1000=10.0
i.e. you need to use floating point arithmetic, not integer arithmetic.
There are numerous other issues with your code as pointed out in my previous comment, so this answer is more of a code review and suggested approach than anything else.
You can batch updates to runLater as in James's answer to Throttling javafx gui updates. But for an update rate of 100 hertz max, it isn't going to make a lot of difference performance-wise as JavaFX generally operates on a 60 hertz pulse cycle, unless you really overload it (which you aren't really doing in your example). So the savings you get by throttling updates will be pretty minimal.
Here is a sample you can try out (it uses James's input throttling technique):
import javafx.application.*;
import javafx.beans.property.DoubleProperty;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
public class InputApp extends Application {
private final ToggleButton controlButton = new ToggleButton("Start");
private final Rectangle box = new Rectangle(100, 100, Color.BLUE);
private final Label brightness = new Label();
private final Label frequencyLabel = new Label();
private final Slider frequency = new Slider(1, 100, 10);
private InputTask task;
#Override
public void start(Stage stage) throws Exception {
// initialize bindings.
brightness.textProperty().bind(
box.opacityProperty().asString("%.2f")
);
frequencyLabel.textProperty().bind(
frequency.valueProperty().asString("%.0f")
);
frequency.valueChangingProperty().addListener((observable, oldValue, newValue) -> {
if (controlButton.isSelected()) {
controlButton.fire();
}
});
// start and stop the input task.
controlButton.selectedProperty().addListener((observable, wasSelected, isSelected) -> {
if (isSelected) {
task = new InputTask(
(int) frequency.getValue(),
box.opacityProperty()
);
Thread inputThread = new Thread(task, "input-task");
inputThread.setDaemon(true);
inputThread.start();
controlButton.setText("Stop");
} else {
if (task != null) {
task.cancel();
}
controlButton.setText("Start");
}
});
// create the layout
VBox layout = new VBox(
10,
frequency,
new HBox(5, new Label("Frequency: " ), frequencyLabel, new Label("Hz"),
controlButton,
box,
new HBox(5, new Label("Brightness: " ), brightness)
);
layout.setPadding(new Insets(10));
// display the scene
stage.setScene(new Scene(layout));
stage.show();
}
// simulates accepting random input from an input feed at a given frequency.
class InputTask extends Task<Void> {
private final DoubleProperty changeableProperty;
private final long sleeptime;
final AtomicLong counter = new AtomicLong(-1);
final Random random = new Random(42);
public InputTask(int inputFrequency, DoubleProperty changeableProperty) {
this.changeableProperty = changeableProperty;
this.sleeptime = (long) ((1.0 / inputFrequency) * 1_000);
}
#Override
protected Void call() throws InterruptedException {
long count = 0 ;
while (!Thread.interrupted()) {
count++;
double newValue = random.nextDouble(); // input simulation
if (counter.getAndSet(count) == -1) {
Platform.runLater(() -> {
changeableProperty.setValue(newValue);
counter.getAndSet(-1);
});
}
Thread.sleep(sleeptime);
}
return null;
}
}
public static void main(String[] args) {
System.out.println(1.0/100*1000);
}
}
I need help with a "paint" program. I've got the GUI established, but I'm having issues with the actual drawing portion of the program. Everything I draw disappears immediately after I draw it, and I can't figure out why.
Here is what I have so far:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JPaint extends JFrame implements ActionListener, MouseListener, MouseMotionListener {
int x, y, x2, y2;
private int select = 0;
private Graphics g;
private PaintPanel DrawPanel = new PaintPanel(this);
private JPanel ButtonPanel = new JPanel();
private JTextArea Draw = new JTextArea(20,20);
private JButton jbtRed = new JButton("Red");
private JButton jbtGreen = new JButton("Green");
private JButton jbtBlue = new JButton("Blue");
private JButton jbtErase = new JButton("Eraser");
private JButton jbtClear = new JButton("Clear");
PaintPanel l=new PaintPanel(this);
public JPaint(){
super("Java Paint");
setSize(480,320);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//build draw panel
DrawPanel.setBackground(Color.WHITE);
add(DrawPanel, BorderLayout.CENTER);
DrawPanel.setVisible(true);
//build button panel
ButtonPanel.add(jbtRed);
ButtonPanel.add(jbtGreen);
ButtonPanel.add(jbtBlue);
ButtonPanel.add(jbtErase);
ButtonPanel.add(jbtClear);
add(ButtonPanel, BorderLayout.SOUTH);
ButtonPanel.setVisible(true);
jbtRed.addActionListener(this);
jbtGreen.addActionListener(this);
jbtBlue.addActionListener(this);
jbtErase.addActionListener(this);
jbtClear.addActionListener(this);
DrawPanel.addMouseMotionListener(this);
DrawPanel.addMouseListener(this);
}
public void actionPerformed(ActionEvent e){
if(e.getSource() == jbtRed){
DrawPanel.setToolTipText("Color set to 'Red'");
select = 1;
}
if(e.getSource() == jbtGreen){
DrawPanel.setToolTipText("Color set to 'Green'");
}
if(e.getSource() == jbtBlue){
DrawPanel.setToolTipText("Color set to 'Blue'");
}
if(e.getSource() == jbtErase){
DrawPanel.setToolTipText("Erase Selected");
}
if(e.getSource() == jbtClear){
DrawPanel.setToolTipText("Drawing cleared");
}
}
#Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
DrawPanel.repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
}
#Override
public void mouseReleased(MouseEvent e) {
x2 = e.getX();
y2 = e.getY();
DrawPanel.repaint();
}
}
class PaintPanel extends JPanel
{
JPaint p;
PaintPanel(JPaint in){
p=in;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// clear the screen
g.setColor(Color.white);
g.setColor(Color.RED);
g.drawLine(p.x, p.y, p.x2, p.y2);
p.x2 = p.x;
p.y2 = p.y;
}
}
class Run_JPaint {
public static void main(String[] args){
JPaint P = new JPaint();
P.setVisible(true);
}
}
You would probably want to remove the following line of code:
super.paintComponent(g);
from inside your PaintPanel class. Otherwise with each draw command your GUI resets the screen.
Good Luck!
I have a problem with a Context menu in JavaFx 2:it never disappers when I left click on the graph of the JFXPanel
Does anybody knows how to solve this problem?
Thanks
Here is my code
final ContextMenu cm = new ContextMenu();
MenuItem chartItem1 = new MenuItem("Chart Settings");
cm.getItems().add(chartItem1);
getScene().setOnMouseReleased(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
if(cm.isShowing()){
cm.hide();
}
if(mouseEvent.getButton() == MouseButton.SECONDARY)
{
cm.show(getScene().getRoot(), mouseEvent.getScreenX(), mouseEvent.getScreenY());
}
}
});
chartItem1.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
dialogs.ChartFormat cs = new dialogs.ChartFormat(null, true);
cs.setLocationRelativeTo(null);
cs.setVisible(true);
}
});
Reproduced the described behavior. Don't know the reason but you can use ContextMenu#hide():
final ContextMenu cm = new ContextMenu();
MenuItem menuItem = new MenuItem("Item 1");
menuItem.addEventHandler(EventType.ROOT, new EventHandler<Event>() {
#Override
public void handle(Event t) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JPanel messagePane = new JPanel();
messagePane.add(new JLabel("label"));
JDialog jDialog = new JDialog();
jDialog.getContentPane().add(messagePane);
jDialog.pack();
jDialog.setVisible(true);
}
});
}
});
cm.getItems().add(menuItem);
scene.setOnMouseReleased(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
// if(cm.isShowing())
cm.hide();
if (mouseEvent.getButton() == MouseButton.SECONDARY) {
cm.show(lineChart, mouseEvent.getScreenX(), mouseEvent.getScreenY());
}
}
});
Also you can check out these links:
http://pixelduke.wordpress.com/2011/12/11/popupmenu-in-javafx/
http://javafx-jira.kenai.com/browse/RT-17853
http://javafx-jira.kenai.com/browse/RT-14899
Adding sample code to your question would be more descriptive.