I'm trying to create a textfield with a title embedded in the field border like:
Following the solution posted here I've created a .java file called TitledBorder.java within my src>main>java directory. My FXML is in the src>main>resources directory and I've added:
<?import TitledBorder?> at the top and it shows no error like:
I then added this code to the FXML
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<TitledBorder title="Email" >
<TextField fx:id="emailField" prefHeight="44.0" prefWidth="143.0" />
</TitledBorder>
</children>
</HBox>
and it shows no error either. I then launch my main method which is in a class also in src>main>java but it gets an error in the .fxml saying javafx.fxml.LoadException:
/C:/Users/ME/Documents/Automation/target/classes/demofxml.fxml
and
Caused by: java.lang.ClassNotFoundException
at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2899)
I'm not sure why it references "/target/classes/..." as opposed to "/src/main/java/...".
This is the only FXML example I've found so I'm confused why I'm getting an error upon compiling, yet no errors are shown prior? Removing all reference to TitledBorder allows all my code to function/compile properly. Since its in the src package I use this code in FXML to connect w/ controller fx:controller="loadController">. CSS is added properly too.
Thoughts?
The line
<?import TitledBorder?>
implies that you put the TitledBorder.java file to default package (i.e. no package declaration in source code of this file). However FXMLLoader's source code checks the imports in FXML file and splits package path name and class name in loadType(...) below, to load the imported class later with loadTypeForPackage():
private Class<?> loadType(String name, boolean cache) throws ClassNotFoundException {
int i = name.indexOf('.');
int n = name.length();
while (i != -1
&& i < n
&& Character.isLowerCase(name.charAt(i + 1))) {
i = name.indexOf('.', i + 1);
}
if (i == -1 || i == n) {
throw new ClassNotFoundException();
}
String packageName = name.substring(0, i);
String className = name.substring(i + 1);
Class<?> type = loadTypeForPackage(packageName, className);
if (cache) {
classes.put(className, type);
}
return type;
}
// TODO Rename to loadType() when deprecated static version is removed
private Class<?> loadTypeForPackage(String packageName, String className) throws ClassNotFoundException {
return getClassLoader().loadClass(packageName + "." + className.replace('.', '$'));
}
The imported class name is "TitledBorder" so the variable i at the 1st line in loadType method will be evaluated as name.indexOf('.') = -1, and will throw ClassNotFoundException in the next lines of code.
Generally it is bad practice to use default packages. Put the TitledBorder.java into some package and import it as
<?import my.some.package.TitledBorder?>
Related
I am making a media player using Javafx and VLCJ.
The app contains a list view in which all the Media files. i.e. audio and video that the user selected are listed. Its like a playlist.
I want to show the total Play time of the entire playlist.
I also want to display the duration of individual media at the side.
e.g.
1> my_visiting_video.mp4 | 01:21:35
2> avengers_end_game.flv | 02:13:40
TotalDuration: 03:35:15
above is the sample of my playlist that I would like to display in the app.
Following is what I did
DMediaPlayer.java
import uk.co.caprica.vlcj.factory.MediaPlayerFactory;
import uk.co.caprica.vlcj.javafx.fullscreen.JavaFXFullScreenStrategy;
import uk.co.caprica.vlcj.javafx.videosurface.ImageViewVideoSurface;
import uk.co.caprica.vlcj.player.base.MediaPlayer;
import uk.co.caprica.vlcj.player.base.MediaPlayerEventAdapter;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
public class DMediaPlayer implements MediaPlayerInterface {
private ImageView mediaView;
private final MediaPlayerFactory mediaPlayerFactory;
private final EmbeddedMediaPlayer embeddedMediaPlayer;
public DMediaPlayer() {
this.mediaPlayerFactory = new MediaPlayerFactory();
this.embeddedMediaPlayer = mediaPlayerFactory.mediaPlayers().newEmbeddedMediaPlayer();
this.mediaView = new ImageView();
this.mediaView.setPreserveRatio(true);
embeddedMediaPlayer.videoSurface().set(new ImageViewVideoSurface(this.mediaView));
}
#Override
public void load(String filePath) throws FileNotFoundException {
embeddedMediaPlayer.media().startPaused(filePath);
embeddedMediaPlayer.controls().setPosition(0f);
}
#Override
public ImageView getMediaView(){
return mediaView;
}
}
The above class returns a ImageView i.e. DMediaPlayer().getMediaView()
and this ImageView is added inside another class that controls all the playbacks, As well as that class has the playlist. For now the playlist only displays the available media files audio/video.
It works fine.
But I want to add a new feature in which the list view not only displays the media files but also some additional information like total play time of the entire playlist and the play time of individual media file.
following is what I did.
File[] mediaList; // it is initialized in the constructor
private void updatePlayList(){
CompletableFuture.runAsync(() -> {
long totalDur = 0;
MediaPlayerFactory factory = new MediaPlayerFactory();
EmbeddedMediaPlayer player = factory.mediaPlayers().newEmbeddedMediaPlayer();
for (int i = 0; i < mediaList.length; i++){
long mediaDur = 0;
player.media().startPaused(mediaList[i].getAbsolutePath());
mediaDur = player.status().length();
totalDur += mediaDur;
drawer.addItem(
(i+1) + "> " +
mediaList[i].getName().substring(0, 25) + "..." +
" | " + millisToDuration(mediaDur)
);
}
drawer.getTotalDuration().setText("Total Duration: " + totalDur);
});
}
drawer is a class that controls ListView.
everything works fine except the vlcj.
It throws the following error.
../include/vlc_xlib.h:46:vlc_xlib_init: Xlib not initialized for threads.
This process is probably using LibVLC incorrectly.
Pass "--no-xlib" to libvlc_new() to fix this.
Exception in thread "ForkJoinPool.commonPool-worker-3" java.lang.IllegalStateException: Not on FX application thread; currentThread = ForkJoinPool.commonPool-worker-3
at javafx.graphics#19/com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:299)
at javafx.graphics#19/com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:458)
at javafx.graphics#19/javafx.scene.Parent$3.onProposedChange(Parent.java:474)
at javafx.base#19/com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
at javafx.base#19/com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
at javafx.controls#19/javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:282)
at javafx.controls#19/javafx.scene.control.skin.LabeledSkinBase.lambda$new$11(LabeledSkinBase.java:219)
at javafx.controls#19/com.sun.javafx.scene.control.LambdaMultiplePropertyChangeListenerHandler.lambda$new$1(LambdaMultiplePropertyChangeListenerHandler.java:88)
at javafx.base#19/javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:86)
at javafx.base#19/com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:181)
at javafx.base#19/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.base#19/javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:104)
at javafx.base#19/javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:111)
at javafx.base#19/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:145)
at javafx.base#19/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:50)
at javafx.base#19/javafx.beans.property.StringProperty.setValue(StringProperty.java:71)
at javafx.controls#19/javafx.scene.control.Labeled.setText(Labeled.java:147)
at com.doruk.dplayer.controllers.PlayerController.lambda$updatePlayList$2(PlayerController.java:108)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Now how can I fix this error, or how can I run the vlcj in the background?
I mentioned background because, additional window opens that plays the video when I run the app.
or am I following the wrong approach...? is there better way...?
all I want is to display the playtime of each media in the list.
I went through several pages in this website but all I could find was to get the total time of the file currently being played. So I followed the above approach. i.e. create a separate media player and start it and then calculate the play time.
I am setting the source property of ResourceDictionary programatically and not from xaml in a Xamarin forms project.
During run time I always get System.invalidOperation exception with the message "Source can only be set from Xaml.
Resources = Resources ?? new ResourceDictionary();
if(Resources.Source == null)
{
Resources.Source = new Uri("/Styles/ActiveTrackerStyle.xaml", UriKind.Relative);
}
Wondering if I am doing anything wrong while setting the Source. Source property has both getter and setter. Any pointers of what is wrong here.
With the help of a colleague, I got it working:
First: Browsing through the Xamarin.Forms' ResourceDictionary class (here, I saw the following property:
public Uri Source {
get { return _source; }
set {
if (_source == value)
return;
throw new InvalidOperationException("Source can only be set from XAML."); //through the RDSourceTypeConverter
}
It seems that you cannot change the source if the private variable "_source" has been set already;
However, the class also have another method "SetAndLoadSource" and in this method the _source variable is set without any checks. Thus, I got it working by doing the following:
var source = new Uri("/Styles/LightResourceDictionary.xaml", UriKind.RelativeOrAbsolute);
var resourceDictionary = new ResourceDictionary();
resourceDictionary.SetAndLoadSource(source, "Styles/LightResourceDictionary.xaml", this.GetType().GetTypeInfo().Assembly, null);
ThemeDictionary.MergedDictionaries.Add(resourceDictionary);
ThemeDictionary.MergedDictionaries.ElementAt(0).Source = source;
Note that "ThemeDictionary" is the x:Name of my MergedDictionary:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="ThemeDictionary">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/DarkResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
I accidentally removed the references from one of my projects and then carefully put them back in. However now I am throwing errors in code the was functioning perfectly so I think I must still be missing a reference unless something else was broken in the process. Here is the current error:
The variable 'button1' is either undeclared or was never assigned.
But here is the code in Form1.Designer.cs:
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
...
//
// button1
//
this.button1.Location = new System.Drawing.Point(235, 382);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(125, 23);
this.button1.TabIndex = 0;
this.button1.Text = "Generate Report";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
...
this.Controls.Add(this.button1);
...
private System.Windows.Forms.Button button1;
The last seven lines are all throwing this error. Any advice is appreciated.
Regards.
EDIT: Here is code relevant to the comments:
public partial class Severity3RetailNetworkTrackingLog : Form
{
public Severity3RetailNetworkTrackingLog()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
Where Form1 has been changed to Severity3RetailNetworkTrackingLog.
I suspect you are missing the member variable definition
class Form1 {
/* lots of windows form designer code */
/* some other member variables */
System.Windows.Forms.Button button1;
}
Within your class definition.
Turns out that VS Express 2010 was just misbehaving. I commented out all of the offending code and still got the same errors with the same line numbers. So I closed and opened VS and everything is back to normal.
I'm using this for my code, it outputs to the xml file perfectly, but it adds an ' = ' sign after the element name even though only one of my elements has an attribute.
I suppose I could do something like
if(reader.Getattribute != "")
// I made that up on the spot, I'm not sure if that would really work
{
Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
}
else
{
Console.WriteLine("<{0}>", reader.Name);
}
but is there a cleaner way to code that?
My code (without workaround)
using System;
using System.Xml;
using System.IO;
using System.Text;
public class MainClass
{
private static void Main()
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter w = XmlWriter.Create(#"Path\test.xml", settings);
w.WriteStartDocument();
w.WriteStartElement("classes");
w.WriteStartElement("class");
w.WriteAttributeString("name", "EE 999");
w.WriteElementString("Class_Name", "Programming");
w.WriteElementString("Teacher", "James");
w.WriteElementString("Room_Number", "333");
w.WriteElementString("ID", "2324324");
w.WriteEndElement();
w.WriteEndDocument();
w.Flush();
w.Close();
XmlReader reader = XmlReader.Create(#"Path\test.xml");
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
break;
case XmlNodeType.Text:
Console.WriteLine(reader.Value);
break;
case XmlNodeType.CDATA:
Console.WriteLine("<[CDATA[{0}]>", reader.Value);
break;
case XmlNodeType.ProcessingInstruction:
Console.WriteLine("<?{0} {1}?>", reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
Console.WriteLine("<!--{0}-->", reader.Value);
break;
case XmlNodeType.XmlDeclaration:
Console.WriteLine("<?xml version='1.0'?>");
break;
case XmlNodeType.Document:
break;
case XmlNodeType.DocumentType:
Console.WriteLine("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value);
break;
case XmlNodeType.EntityReference:
Console.WriteLine(reader.Name);
break;
case XmlNodeType.EndElement:
Console.WriteLine("</{0}>", reader.Name);
break;
}
}
}
}
Output
<?xml version='1.0'?>
<classes = >
<class = EE 999>
<Class_Name = >
Programming
</Class_Name>
<Teacher = >
James
</Teacher>
<Room_Number = >
333
</Room_Number>
<ID = >
2324324
</ID>
</class>
</classes>
Because this line
case XmlNodeType.Element:
Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
break;
Always writes the '=' without checking.
A rough fix :
case XmlNodeType.Element:
Console.WriteLine("<{0}", reader.Name);
if (reader.HasAttributes)
// Write out attributes
Console.WriteLine(">");
break;
But why are you using the XmlReader at all? It is cumbersome and only useful when dealing with huge Xml streams.
If your datasets are not >> 10 MB then take a look at XDocument or XmlDocument
The XmlWriter in your Example can be replaced by (rough approx):
// using System.Xml.Linq;
var root = new XElement("classes",
new XElement("class", new XAttribute("name", "EE 999"),
new XElement("Class_Name", "Programming"),
new XElement("Teacher", "James")
));
root.Save(#"Path\test.xml");
var doc = XDocument.Load(#"Path\test.xml");
// doc is now an in-memory tree of XElement objects
// that you can navigate and query
And here is an intro
I don't know exactly what you're trying to accomplish but personally I would create a .NET class representing your class element with properties identifying the sub elements then use System.Xml.Serialization.XmlSerializer to write or read it from a file.
Here is an example:
using System.Xml.Serialization;
public class MyClasses : List<MyClass>{}
public class MyClass{
public String Teacher{ get; set; }
}
void main(){
MyClasses classList = new MyClasses();
MyClass c = new MyClass();
c.Teacher = "James";
classList.Add(c);
XmlSerializer serializer = new XmlSerializer(classList.GetType());
serializer.Serialize(/*Put your stream here*/);
}
And, after leaving setting up your stream as an exercise to the reader, blamo, you're done outputing an XML representation of your object to some stream. The stream could be a file, string, whatever. Sorry for nasty C# (if its nasty) I use VB.NET everyday so the syntax and keywords may be a little off.
Update
I added some code to show how to serialize a collection of the classes. If nodes aren't coming out named correctly there are attributes you can add to your class properties, just do a quick google for them.
Update again
Sorry, its hard to explain when we're using the same word to mean two different things. Lets say you're trying to represent a bucket of bricks. You would write a C# class called Brick and a C# class called Bucket that inherited from List<Brick> your Brick would have a property called Color. You would then make all your bricks with different colors and fill the bucket with your bricks. Then you would pass your bucket to the serializer and it would give you something like:
<Bucket>
<Brick>
<Color>
blue
</Color>
</Brick>
</Bucket>
The serializer builds the XML for you from the definitions of your classes so you don't have to worry about the details. You can read more about it here and here
I'm newish to flex an have recently hit a snag casting.
this is the code I'm running.
/**
* return background definition depending on time
*/
private function findBackgroundItem( relativeTime : Number ) : CSBackgroundItem
{
if( this.backgroundItems == null ) return null;
var result :CSBackgroundItem = null;
var relative:Date = new Date(relativeTime);
for( var i : Number = 0; i < this.backgroundItems.length; i++ )
{
// backgroundItems is an Ilist of CSBackgroundItem.
var colourItem : CSBackgroundItem = CSBackgroundItem( this.backgroundItems.getItemAt( i ) );
// other stuff here
}
return result;
}
The problem occurs when the IList.getItemsAt() result is cast to the CSBackgroundItem variable colourItem. The following error is thrown
TypeError: Error #1034: Type Coercion failed: cannot convert com.mystuff::CSBackgroundItem#650e8dd1 to com.mystuff.CSBackgroundItem.
If I use the 'as' keyword I get cast results in the colourItem being null. Using the debugger shows that the list is not empty and is indeed populated with CSBackgroundItem objects.
Now this is the wacky bit.. this code works, the first time the module it's in loads.. subsequent loads (after unloading it) throw the exception.
Can anyone shed any light on why this might happen?
FYI, a type loaded into a child ApplicationDomain can be cast to a type (that it extends/implements) in the parent ApplicationDomain.
Eg.
loader.applicationDomain = ApplicationDomain.currentDomain; // parent domain
loader.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain); // child domain
loader.applicationDomain = new ApplicationDomain(); // new domain
I think I may have found the answer..
My guess is the module is loading in a different ApplicationDomain.. which would mean you can't cast from the same type in the current domain..
As I understand this is vaguely similart to different Java ClassLoaders loading the same class.
I'll post again once I've confirmed it
Yup.. that works..
here is the fix i used in MXML style..
<mx:ModuleLoader id="loader" x="10" y="10" width="100%" height="100%" applicationDomain="{ApplicationDomain.currentDomain}"/>
the equivilant actionscript would be
loader.applicationDomain = ApplicationDomain.currentDomain;